实体框架代码首先使用TPH继承外键,在Database表中添加其他列

时间:2012-07-02 12:08:33

标签: entity-framework-4.1 entity

我遇到了使用TPH的EF Code First问题。我在表中得到了两个不在模型中的列。

我有一个类结构如下:

 public class TestBase
    {
        public int Id { get; set; }


        public string Name { get; set; }
        [ForeignKey("TestMaster")]
        public string TestMaster_Id { get; set; }

        public TestMaster TestMaster { get; set; }

    }

    public class TestInherit1 : TestBase
    {
        public string Val1 { get; set; }
    }

    public class TestInherit2 : TestBase
    {
        public string  val2 { get; set; }
    }

    public class TestMaster
    {
        [Key]
        public string Id { get; set; }

        public virtual ICollection<TestInherit1> Inherit1List { get; set; }
        public virtual ICollection<TestInherit2> Inherit2List { get; set; }
    }

在DBContext中,我有以下内容:

    public DbSet<TestMaster> TestMaster
    {
        get;
        set;
    }

    public DbSet<TestBase> TestBase
    {
        get;
        set;
    }

    [NotMapped]
    public DbSet<TestInherit1> TestInherit1
    {
        get;
        set;
    }

    [NotMapped]
    public DbSet<TestInherit2> TestInherit2
    {
        get;
        set;
    }

以下是EF生成的表格结构:

[TestBases]

    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [TestMaster_Id] [nvarchar](128) NULL,
    [Val1] [nvarchar](max) NULL,
    [val2] [nvarchar](max) NULL,
    [Discriminator] [nvarchar](128) NOT NULL,
    [TestMaster_Id1] [nvarchar](128) NULL,
    [TestMaster_Id2] [nvarchar](128) NULL

[TestMasters](
    [Id] [nvarchar](128) NOT NULL

如果查看TestBases表,则会生成另外两列TestMaster_id1和TestMaster_Id2,这些列未在类中定义。 EF正在插入这两列。我已经在TestMaster_Id列上定义了外键。我究竟做错了什么?。我不想要这两列。

1 个答案:

答案 0 :(得分:1)

您的表包含更多未定义的列:Val1Val2Discriminator如果您不想映射派生类型,也不应映射。但是如果你没有映射这些类型,你将永远不会从EF获得这些实例,你永远无法将这些实例存储到EF。

您的NotMapped属性使用不正确。它必须在实体类型或实体类型内的属性上声明。此外,如果您不想映射派生类型,则不应为它们创建DbSet属性。

属性的正确用法是:

[NotMapped]
public class TestInherit1 : TestBase
{
    public string Val1 { get; set; }
}

或者:

[NotMapped]
public virtual ICollection<TestInherit1> Inherit1List { get; set; }

当您的实体被映射时,这也是您获得两个新外键的原因 - 您将导航属性定义为派生类型。它们中的每一个都需要自己的外键,因为EF无法重新定义派生类中父属性的映射。

如果只想在父实体中声明单个外键,则必须只为父级定义单个导航属性:

public virtual ICollection<TestBase> TestList { get; set; }