代码之家  ›  专栏  ›  技术社区  ›  Mark Feldman

将公共类用于继承和成员(代码优先)

  •  0
  • Mark Feldman  · 技术社区  · 5 年前

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

    所以从概念上讲,人是有名字的动物,他们的宠物也是有名字的动物。我的上下文包含一组人,但是

    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 我有一张桌子吗 Id Name 字段,这是我预期的行为。同样,如果我删除 Animal 身份证件 Pet_Name 字段,这也是我期望的行为。我想要的是一张有 身份证件 名称 宠物名

    我忍不住觉得我在这里遗漏了一些非常基本的东西,因为我已经在其他的orm上完成了这项工作。有人能告诉我如何使用EF 6.2实现这一点吗?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Mark Feldman    5 年前

    对于将来阅读本文的任何其他人,EF将类视为实体或复杂类型。实体获取自己的表,而复杂类型获取自己的字段作为字段添加到父类中,父类将这些字段作为属性包含。如果您将一个类实例声明为另一个类实例的属性,那么EF会立即假定它是一个实体;如果它看到您试图将它用作继承层次结构中的基类,那么它会假定它是一个复杂类型。当EF已经错误地假设该类型是一个实体,但您试图将其用作复杂类型时,就会出现上面显示的错误。在我看来,如果类没有键属性,EF不应该首先做出假设,但它确实存在。解决方案是从一开始就将其标记为复杂类型 OnModelCreating 功能:

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