2013-04-07 52 views
1

我有以下幾點:EF5代碼優先派生類的外鍵/引用問題

public abstract class InputBase 
{ 
    public virtual ICollection<Data> Data { get; set; } 
} 

public class InputA: InputBase { } 

public class InputB: InputBase { } 

public abstract class Data 
{ 
    public virtual InputA InputA { get; set; } 
    public virtual InputB InputB { get; set; } 
} 

InputA和InputB都使用數據的InputBase的集合。

數據將始終有一個InputA和InputB的實例。

我想通過這個鏈接起來:

modelBuilder.Entity<Data>() 
    .HasRequired(data => data.InputA) 
    .WithMany(input => input.Data) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<Data>() 
    .HasRequired(data => data.InputB) 
    .WithMany(input => input.Data) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<InputA>() 
    .HasRequired(input => input.Data) 
    .WithRequired(data => data.InputA) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<InputB>() 
    .HasRequired(input => input.Data) 
    .WithRequired(data => data.InputB) 
    .WillCascadeOnDelete(false); 

但是,我得到一個MetaDataException,錯誤0040:類型Data_InputA沒有命名空間(...)

定義如何使這項工作?我不想在輸入派生上創建單獨的數據集合,因爲這在邏輯上不正確。

+0

也許這是一個錯誤,但是您的抽象類的InputA和InputB屬性沒有分配屬性名稱。您可以定義它返回的數據類型,但可以設置實際名稱,但實際名稱在您實際要訪問屬性EG時將作爲代碼中的引用:public virtual InputA MyInput1 {get;組; } – Justin 2013-04-07 23:22:55

+0

是的,這是一個錯字:)只是試圖展示這個概念。 – Alex 2013-04-07 23:24:27

+0

爲什麼你的數據類是抽象的? – 2013-04-08 04:14:34

回答

0

這應該可以解決你的問題:

更改此:

public abstract class Data 
{ 
    public virtual InputA InputA { get; set; } 
    public virtual InputB InputB { get; set; } 
} 

注意:如果你所擔心的foreign key,這樣很好。 KeyInputA ObjectInputBase Object相同,因爲我們使用的是Inheritance。因此,Data Structure指示我們執行以下操作。

public abstract class Data 
{ 
    [ForeignKey("InputBase"), DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int? InputBaseId { get; set; } 

    public virtual InputBase InputBase { get; set; }  
} 

如果您InheritanceTable per Type (TPT)

這樣做是爲了派生類:

[Table("InputB")] //This is what your table will be named in your database for derived class 
public class InputA: InputBase { } 

[Table("InputB")] 
public class InputB: InputBase { } 

而且你不需要這樣的:

modelBuilder.Entity<Data>() 
.HasRequired(data => data.InputA) 
.WithMany(input => input.Data) 
.WillCascadeOnDelete(false); 

modelBuilder.Entity<Data>() 
.HasRequired(data => data.InputB) 
.WithMany(input => input.Data) 
.WillCascadeOnDelete(false); 

modelBuilder.Entity<InputA>() 
.HasRequired(input => input.Data) 
.WithRequired(data => data.InputA) 
.WillCascadeOnDelete(false); 

modelBuilder.Entity<InputB>() 
.HasRequired(input => input.Data) 
.WithRequired(data => data.InputB) 
.WillCascadeOnDelete(false); 

您可以刪除部分因爲我們使用了Property Mapping