我遇到了使用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列上定义了外键。我究竟做错了什么?。我不想要这两列。
答案 0 :(得分:1)
您的表包含更多未定义的列:Val1
,Val2
和Discriminator
如果您不想映射派生类型,也不应映射。但是如果你没有映射这些类型,你将永远不会从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; }