If you have more than one navigation property refering to the same entity EF does not know where the inverse navigation property on the other entity belongs to. In your example: Does A.ObjectsOfB
refer to B.ObjectA
or to B.OtherObjectsOfA
? Both would be possible and a valid model.
Now, EF does not throw an exception like "cannot determine relationships unambiguously" or something. Instead it decides that B.ObjectA
refers to a third endpoint in B
which is not exposed as navigation property in the model. This creates the first foreign key in table B
. The two navigation properties in B
refer to two endpoints in A
which are also not exposed in the model: B.ObjectA
creats the second foreign key in table B
and B.OtherObjectsOfA
creates a foreign key in table A
.
To fix this you must specify the relationships explicitely.
Option one (the easiest way) is to use the InverseProperty
attribute:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty("OtherObjectsOfA")]
public virtual ICollection<B> ObjectsOfB { get; set; }
}
This defines that A.ObjectsOfB
is part of a many-to-many relation to B.OtherObjectsOfA
.
The other option is to define the relationships completely in Fluent API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<A>()
.HasMany(a => a.ObjectsOfB)
.WithMany(b => b.OtherObjectsOfA)
.Map(x =>
{
x.MapLeftKey("AId");
x.MapRightKey("BId");
x.ToTable("ABs");
});
modelBuilder.Entity<B>()
.HasRequired(b => b.ObjectA) // or HasOptional
.WithMany()
.WillCascadeOnDelete(false); // not sure if necessary, you can try it
// without if you want cascading delete
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…