1

我在使用 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 列上定义了外键。我究竟做错了什么?。我不想要这两列。

4

1 回答 1

1

您的表包含更多未定义的列:Val1,如果您不想映射派生类型,也不应该映射Val2Discriminator但是,如果您不映射这些类型,您将永远无法从 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; }
于 2012-07-02T12:56:43.320 回答