Entity framework 4.1 实体框架代码首先使用TPH继承外键,在数据库表中添加其他列

Entity framework 4.1 实体框架代码首先使用TPH继承外键,在数据库表中添加其他列,entity-framework-4.1,entity,Entity Framework 4.1,Entity,我面临着EF代码的问题,首先是TPH。我在表中得到了两个模型中没有的额外列 我的班级结构如下: public class TestBase { public int Id { get; set; } public string Name { get; set; } [ForeignKey("TestMaster")] public string TestMaster_Id { get; set; }

我面临着EF代码的问题,首先是TPH。我在表中得到了两个模型中没有的额外列

我的班级结构如下:

 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; }
    }
    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;
    }

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

您的表包含更多未定义的列:
Val1
Val2
Discriminator
,如果您不想映射派生类型,也不应该映射这些列。但如果你不映射这些类型,你将永远无法从EF中获取这些实例,也永远无法将这些实例存储到EF中

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

该属性的正确用法为:

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

[未映射]
公共虚拟ICollection Inherit1List{get;set;}
目前,您的实体已映射,这也是您获得两个新外键的原因—您为派生类型定义了导航属性。它们每个都需要自己的外键,因为EF无法重新定义派生类中父属性的映射

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

public virtual ICollection<TestBase> TestList { get; set; }
公共虚拟ICollection测试列表{get;set;}
如果不想映射派生类型,则表中包含更多未定义的列:
Val1
Val2
Discriminator
也不应映射。但如果你不映射这些类型,你将永远无法从EF中获取这些实例,也永远无法将这些实例存储到EF中

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

该属性的正确用法为:

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

[未映射]
公共虚拟ICollection Inherit1List{get;set;}
目前,您的实体已映射,这也是您获得两个新外键的原因—您为派生类型定义了导航属性。它们每个都需要自己的外键,因为EF无法重新定义派生类中父属性的映射

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

public virtual ICollection<TestBase> TestList { get; set; }
公共虚拟ICollection测试列表{get;set;}
感谢您对“NotMapped”的评论。关于新外键,是否有办法绕过单一导航属性的限制。我试图使用Fluent API映射到同一属性,但随后出现错误“已配置冲突的多重性”。由于项目已经启动,我无法对模型进行任何根本性的更改。我需要删除这些附加列。如果我没有找到解决这个问题的方法,我将不得不为这些额外的外键创建数据库索引,这将影响插入性能。谢谢,具有[NotMapped]属性的解决方案拯救了我的一天!感谢您对“NotMapped”的评论。关于新外键,是否有办法绕过单一导航属性的限制。我试图使用Fluent API映射到同一属性,但随后出现错误“已配置冲突的多重性”。由于项目已经启动,我无法对模型进行任何根本性的更改。我需要删除这些附加列。如果我没有找到解决这个问题的方法,我将不得不为这些额外的外键创建数据库索引,这将影响插入性能。谢谢,具有[NotMapped]属性的解决方案拯救了我的一天!