2016-01-06 59 views
1

我有3個型號,在其領域,如下列:實體框架,表2個的外鍵2頁不同的表

public class RootObject 
{ 
    [Key] 
    public int RootObjectId { get; set; } 
    [ForeignKey("RootObjectId")] 
    public virtual AObject AObject { get; set; } 
    [ForeignKey("RootObjectId")] 
    public virtual BObject BObject { get; set; } 

    public string Name { get; set; } 
} 

public class AObject 
{ 
    [Key] 
    public int AObjectId { get; set; } 

    //Other fields 
} 

public class BObject 
{ 
    [Key] 
    public int BObjectId { get; set; } 

    //Other fields 
} 

我希望它這樣,如果我是目測檢查RootObject表我會請參閱參見RootObjectIdName的列表。爲了方便起見,我們假設偶數編號RootObjectId的映射爲AObjectId,賠率映射到BObjectId。如果我目測檢查AObject,我預計會看到編號爲2,4,6,...的編號爲RootObject的FK。如果要目視檢查BObject,我希望看到編號爲1,3,5,...的是FK的RootObject

目前,當我嘗試這種方法,我得到以下錯誤:

「在更新條目...參照完整性約束違規行爲發生錯誤的從屬角色有不同的價值觀多個主體。」

我試圖刪除RootObject中的FK屬性,但在RootObject中創建了2個填充了ID號的附加列。我不希望這樣,因爲每個RootObject有一個AObject或一個BObject。它不能兼得。

+0

它甚至不能在SQL中完成,更不用說EF。 –

回答

1

對於我而言,您正在尋找的是實體框架中的TPT(Table per Type)方法可能是一種解決方案。適用於你的情況(有很多的方法,但是這個我測試和它的作品):

public class RootObject 
{ 
    [Key] 
    public int RootObjectId { get; set; } 
    public string Name { get; set; } 
} 

[Table("AObjects")] 
public class AObject : RootObject 
{ 
    //Other fields 
    public string AField { get; set; } 
} 

[Table("BObjects")] 
public class BObject : RootObject 
{ 
    //Other fields 
    public string BField { get; set; } 
} 

對於的DbContext類:

public DbSet<RootObject> RootObjects { get; set; } 
public DbSet<AObject> AObjects { get; set; } 
public DbSet<BObject> BObjects { get; set; } 

種子例如:

AObject a1 = new AObject() { Name = "ImA", AField = "adata" }; 
BObject b1 = new BObject() { Name = "ImB", BField = "bdata" }; 
context.AObjects.Add(a1); 
context.BObjects.Add(b1); 
context.SaveChanges(); 
0

我不認爲可以使用ONE列作爲兩個不同表的外鍵。您應該考慮兩個(可選的)FK:

public class RootObject 
{ 
    [Key] 
    public int RootObjectId { get; set; } 

    public int? EvensAObjectId { get; set; } 
    public int? OddsBObjectId { get; set; } 

    [ForeignKey("EvensAObjectId")] 
    public virtual AObject AObject { get; set; } 

    [ForeignKey("OddsBObjectId")] 
    public virtual BObject BObject { get; set; } 

    public string Name { get; set; } 
} 
0

要設置1-0..1的關係,您需要在模型配置期間明確定義關係。

public class Model1 : DbContext 
{ 
    public Model1() 
     : base("name=Model1") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<AObject>() 
      .HasRequired(e => e.RootObject).WithOptional(r => r.AObject); 

     modelBuilder.Entity<BObject>() 
      .HasRequired(e => e.RootObject).WithOptional(r => r.BObject); 

     base.OnModelCreating(modelBuilder); 
    } 

    public virtual DbSet<RootObject> RootObjects { get; set; } 
    public virtual DbSet<AObject> AObjects { get; set; } 
    public virtual DbSet<BObject> BObjects { get; set; } 
} 


public class RootObject 
{ 
    [Key] 
    public int RootObjectId { get; set; } 
    public virtual AObject AObject { get; set; } 
    public virtual BObject BObject { get; set; } 

    public string Name { get; set; } 
} 

public class AObject 
{ 
    [Key] 
    public int AObjectId { get; set; } 

    public virtual RootObject RootObject { get; set; } 
} 

public class BObject 
{ 
    [Key] 
    public int BObjectId { get; set; } 

    public virtual RootObject RootObject { get; set; } 
} 

你會想設置RootObject.AObjectRootObject.BObject時,彷彿已經存在相關的行,當你保存你會得到一個錯誤非常小心。另外,我不認爲有任何方法可以讓EF強制實施每個RootObject都必須具有AObject或BObject的約束,但不能同時使用 - 您需要在代碼中執行該約束。