使用公共类进行继承和成员使用(代码优先)

时间:2019-02-01 04:54:25

标签: entity-framework

我很难先获得EF代码才能从以下实体生成数据库:

public class Person : Animal
{
    public int Id { get; set; }
    public Animal Pet { get; set; }
}

public class Animal
{
    public string Name { get; set; }
}

因此,从概念上讲,人是有名字的动物,而他们的宠物也是有名字的动物。我的上下文包含一系列人,但不是动物,这就是为什么Animal不包含键的原因:

public DbSet<Person> People { get; set; }

如果我尝试先使用代码创建数据库,则会出现以下错误:

System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation:

MyProject.Database.Animal: : EntityType 'Animal' has no key defined. Define the key for this EntityType.
Animals: EntityType: EntitySet 'Animals' is based on type 'Animal' that has no keys defined.

如果删除Pet字段,则会得到一个包含IdName字段的表,这是我的预期行为。同样,如果删除Animal继承,则会得到一个包含IdPet_Name字段的表,这也是我的预期行为。我想要得到的是一个带有IdNamePet_Name字段的表。

不禁感到我在这里缺少一些非常基本的东西,因为我已经在其他ORM上做到了这一点而没有问题。谁能告诉我如何使用EF 6.2做到这一点?

1 个答案:

答案 0 :(得分:0)

对于在将来的EF中阅读此内容的其他任何人,都将类视为实体或复杂类型。实体获得自己的表,而复杂类型获得其自身的字段作为字段添加到包含它们作为属性的父类中。如果您将一个类实例声明为另一个实例的属性,则EF会立即假定它是一个Entity;如果看到您试图将其用作继承层次结构中的基类,则假定它是复杂类型。当EF已经错误地假定类型为Entity,但随后尝试将其用作复杂类型时,将发生上述错误。在我看来,如果类没有键属性,则EF不应首先进行假设,但确实存在。解决方案是从OnModelCreating函数开始就简单地将其标记为复杂类型:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.ComplexType<Animal>();

    base.OnModelCreating(modelBuilder);
}