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
字段,我会得到一个带有Id
和Name
字段的表格,这是我的预期行为。同样,如果我删除Animal
继承,我会得到一个带有Id
和Pet_Name
字段的表,这也是我的预期行为。我想要得到的是一个带有Id
,Name
和Pet_Name
字段的表。
不禁觉得我在这里遗漏了一些非常基本的东西,因为我已经在其他 ORM 上做到了这一点而没有问题。谁能告诉我如何使用 EF 6.2 做到这一点?
解决方案
对于将来阅读此内容的任何其他人,EF 将类视为实体或复杂类型。实体拥有自己的表,而复杂类型拥有自己的字段,作为字段添加到包含它们作为属性的父类中。如果您将一个类实例声明为另一个类的属性,那么 EF 会立即假定它是一个实体;如果它看到你试图将它用作继承层次结构中的基类,那么它会假定它是一个复杂类型。上面显示的错误发生在 EF 已经错误地假定类型是实体但您尝试将其用作复杂类型时。在我看来,如果类没有关键属性,EF 不应该首先做出假设,但确实存在。解决方案是从OnModelCreating
函数的开头简单地将其标记为复杂类型:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<Animal>();
base.OnModelCreating(modelBuilder);
}
推荐阅读
- android - 房间查询 BETWEEN 日期不返回结果
- flutter - 使用 Flutter 加载非常简单的图像非常慢
- sql-server - Azure 数据工厂 - 在查询中引用查找活动
- javascript - 验证 html 中的特定隐藏输入字段是否为空
- firebase - Firestore - 意外读取
- java - 将LibGdx项目导入java后出现错误
- drupal - 使用 Drush 更新 Drupal Core 说它更新成功但没有?
- javascript - 无法从 jquery/javascript 调用 ahref
- laravel - 当数据透视表具有唯一字段时更新 Laravel 数据透视表
- microsoft-graph-api - 使用 Microsoft Graph API 更新邮件正文内容