2013-04-07 43 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