EF5代码优先派生类外键/引用问题

时间:2013-04-07 23:16:48

标签: c# .net entity-framework entity-framework-5 code-first

我有以下内容:

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未在命名空间中定义(...)

我该如何使这项工作?我不想在输入派生上创建单独的数据集合,因为这在逻辑上是不正确的。

1 个答案:

答案 0 :(得分:0)

这可以解决您的问题:

改变这个:

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

To:如果你担心foreign key,那就没关系。 Key的{​​{1}}与InputA Object相同,因为我们使用InputBase Object。因此,Inheritance要求我们执行以下操作。

Data Structure

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

对派生类执行此操作:

Table 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);