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:
- Remove the
SomeOtherModelIDandSomeOtherModelproperties onAuditableModel - Code the relationship on
SomeOtherModelin theDbContext‘sOnModelCreatingmethod 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?
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
AuditableModelrefering toSomeOtherModeland a single navigation property onSomeOtherModelrefering toAuditableModel. 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).