[英]Using both many-to-many and one-to-many to same entity
我在EF Code-First中有一個多對多關聯(正如本問題中所解釋的那樣),我也希望對同一個實體使用一對多關系。 問題是EF無法生成正確的數據庫方案。 碼:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<B> ObjectsOfB { get; set; }
}
public class B
{
public int Id { get; set; }
public virtual A ObjectA { get; set; }
public virtual ICollection<A> OtherObjectsOfA { get; set; }
}
當我刪除B類的ObjectA屬性時,會正確生成多對多關聯。 當生成不正確時,實體B獲得2個外鍵到A,實體A獲得1個外鍵到B(如多對一關系)。
如果您有多個導航屬性引用同一實體,則EF不知道另一個實體上的反向導航屬性所屬的位置。 在您的示例中: A.ObjectsOfB
是指B.ObjectA
還是B.OtherObjectsOfA
? 兩者都是可能的並且是有效的模型。
現在,EF不會拋出像“無法明確地確定關系”之類的異常。 相反,它決定B.ObjectA
引用B
的第三個端點,它不作為模型中的導航屬性公開。 這將在表B
創建第一個外鍵。 B
的兩個導航屬性引用A
中的兩個端點,這兩個端點也未在模型中公開: B.ObjectA
在表B
創建第二個外鍵,而B.OtherObjectsOfA
在表A
創建外鍵。
要解決此問題,您必須明確指定關系。
選項一(最簡單的方法)是使用InverseProperty
屬性:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty("OtherObjectsOfA")]
public virtual ICollection<B> ObjectsOfB { get; set; }
}
這定義A.ObjectsOfB
是A.ObjectsOfB
的多對多關系的B.OtherObjectsOfA
。
另一種選擇是在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
}
如果表B具有表A的外鍵,則類B具有到A的導航屬性,並且A具有到ICollection<A>
導航屬性。
如果表B與表A具有多對多關系,則類A必須具有ICollection<B>
並且類B必須具有ICollection<A>
。
試試這個,也許這會澄清你對EF的要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.