为了避免使用层次表(TPH),我一直在寻找如何在我的数据库模型中最好地实现基于具体类的继承(TPC)的示例。我发现了官方文档和这篇文章。
以下是一些带有简单继承的模拟类。
应用程序成功运行,但当我返回到数据库时,我发现了三个(3)表,而不是我预期的两个(2)。经过一些测试,似乎创建了“BaseEntity”表,但从未使用。除了这个空的孤立表之外,一切都正常工作。
我尝试调整DbModelBuilder配置,最终删除了“BaseEntity”配置,得到了预期结果:两个(2)表,每个表都具有正确的属性并正常工作。
我进行最后一次测试,删除所有DbModelBuilder配置,仅包括“Person”和“Business”的两个(2)DbSet属性,并再次测试。
令我惊讶的是,项目构建成功并与数据库连接,只创建了两个表格,其中包括从“BaseEntity”类继承的所有类属性。我可以无问题地进行CRUD操作。
经过多次测试,我没有发现任何问题,并且我无法重现两篇文章警告的重复键错误。
引用块:
“对数据库的更改已成功提交,但在更新对象上下文时出现错误。ObjectContext可能处于不一致的状态。内部异常消息:AcceptChanges无法继续,因为对象的关键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges之前,请确保关键值是唯一的。”
以下是一些带有简单继承的模拟类。
public class BaseEntity
{
public BaseEntity()
{
ModifiedDateTime = DateTime.Now;
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime ModifiedDateTime { get; set; }
}
public class Person : BaseEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Business : BaseEntity
{
public string Name { get; set; }
public string Location { get; set; }
}
这是两篇文章中使用的DbModelBuilder配置示例。
modelBuilder.Entity<BaseEntity>()
.Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Person>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Person");
});
modelBuilder.Entity<Business>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Business");
});
应用程序成功运行,但当我返回到数据库时,我发现了三个(3)表,而不是我预期的两个(2)。经过一些测试,似乎创建了“BaseEntity”表,但从未使用。除了这个空的孤立表之外,一切都正常工作。
我尝试调整DbModelBuilder配置,最终删除了“BaseEntity”配置,得到了预期结果:两个(2)表,每个表都具有正确的属性并正常工作。
我进行最后一次测试,删除所有DbModelBuilder配置,仅包括“Person”和“Business”的两个(2)DbSet属性,并再次测试。
public DbSet<Person> People { get; set; }
public DbSet<Business> Businesses { get; set; }
令我惊讶的是,项目构建成功并与数据库连接,只创建了两个表格,其中包括从“BaseEntity”类继承的所有类属性。我可以无问题地进行CRUD操作。
经过多次测试,我没有发现任何问题,并且我无法重现两篇文章警告的重复键错误。
引用块:
“对数据库的更改已成功提交,但在更新对象上下文时出现错误。ObjectContext可能处于不一致的状态。内部异常消息:AcceptChanges无法继续,因为对象的关键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges之前,请确保关键值是唯一的。”
- 我很好奇为什么这些示例使用MapInheritedProperties属性; 这是一种过时的方法吗?
- 为什么两个示例都说要包括“BaseEntity”的配置属性,但包括“BaseEntity”类的DbSet属性或任何DbModelBuilder配置会导致创建未使用的表。
- 关于唯一键错误的参考文章警告; 我无法复现该错误,并且已经多次测试了将主键设置为由数据库生成的int和由数据库生成的guid。关于这个错误的信息是否也已过时,或者是否有一个测试可以运行以产生该错误?