Reputation: 5290
Say I have the following POCO classes:
public class AuditableModel
{
public int ID { get; set; }
public int? SomeOtherModelID { get; set; }
[ForeignKey("SomeOtherModelID")]
public SomeOtherModel SomeOtherModel { get; set; }
public int LastUpdateBy { get; set; }
[ForeignKey("LastUpdateBy")]
public AuditableModel LastUpdateByModel { get; set; }
}
public class SomeOtherModel
{
public int ID { get; set; }
public int LastUpdateBy { get; set; }
[ForeignKey("LastUpdateBy")]
public AuditableModel LastUpdateByModel { get; set; }
}
In this example, I have a foreign key on AuditableModel
pointing to SomeOtherModel
and a foreign key on SomeOtherModel
pointing to AuditableModel
, both are a one-to-many, both should be unidirectional.
When trying to query my AuditableModel
class, I get the "Unable to determine the principal end of an association" exception. There are two ways I've found to get around this exception:
SomeOtherModelID
and SomeOtherModel
properties on AuditableModel
SomeOtherModel
in the DbContext
's OnModelCreating
method using the fluent API.I'll implement using the fluent API, but would have rather done it completely via conventions and data annotations. Is there a way, or am I stuck defining these relationships via configuration?
Upvotes: 2
Views: 907
Reputation: 177163
I agree with @Eranga. This only works with Fluent API. What exactly is going wrong here is that conventions detect a single navigation property on AuditableModel
refering to SomeOtherModel
and a single navigation property on SomeOtherModel
refering to AuditableModel
. Mapping conventions try to create a one-to-one relationship (because neither of the navigation properties is a collection) between the entities. Because it's not clear what's the principal and what the dependent you get this exception.
There is no data annotation attribute to resolve this problem, i.e. to tell EF that actually two relationsships should be created with a not-exposed many-side on each relationship. You can only configure this in Fluent API (using the WithMany()
overload without a parameter).
Upvotes: 1
Reputation: 32447
Removing the SomeOtherModelID
on AuditableModel
may not be an option depending on your domain model.
Attribute based/Convention based configuration has limitations. So in this case you will have to fallback to Fluent API because the relationship inferred by conventions is not what you need.
Upvotes: 1