簡體   English   中英

同時使用多對多和一對多同一實體

[英]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.ObjectsOfBA.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM