2011-11-22 60 views
5

我在EF Code-First中有一個多對多關聯(如this問題所述),我想使用one-to對同一個實體也是如此。問題是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外鍵(如多對一關係)。

回答

15

如果您有多個導航屬性引用同一個實體,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是許多一對多關係B.OtherObjectsOfA的一部分。

另一種選擇是,以流利的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 
} 
+0

謝謝你的回答!但是,對於這兩種解決方案,我都會得到以下異常:'在EntityFramework.DLL中發生'System.InvalidOperationException'類型的第一次機會異常' – Marthijn

+0

更正:流暢的解決方案(我的錯誤..),非常感謝!任何想法爲什麼'InverseProperty'引發異常? – Marthijn

+0

@Henkie:應用程序真的崩潰嗎? 「第一次機會異常」通常不是問題,只在調試器輸出窗口中顯示。通常它可以被忽略。 – Slauma

0

如果表B具有表A的外鍵,那麼類B具有導航屬性到A,導航屬性爲ICollection<A>
如果表B與表A有多對多的關係,那麼A級必須有ICollection<B>,B級必須有ICollection<A>

嘗試一下,也許這會明確你的要求從EF。

+0

我忘了ICollection中添加'類A'在我的代碼示例中的許多-to-many關聯。現在已經修復了。 – Marthijn

+0

@Henkie:很高興能幫到你:) – Naor