在努力避免使用表每个层级(TPH)我一直在寻找如何最好地实现我的数据库表的模型每个具体类(TPC)继承的例子。我碰到href=\"msdn.microsoft/en-us/data/jj591617#2.6\" rel=\"nofollow\">官方文档并的这篇文章。
下面是一些模拟补课一些简单的继承。
公共类BaseEntity {公共BaseEntity() { ModifiedDateTime = DateTime.Now; } [关键] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)公众诠释标识{搞定;组; } 公众的DateTime ModifiedDateTime {搞定;组; } } 公共类人:BaseEntity {公共字符串名字{获得;组; } 公共字符串名字{获得;组; } } 公共类业务:BaseEntity {公共字符串名称{;组; } 公共字符串位置{搞定;组; } }
两篇文章在每例中使用的DbModelBuilder配置。
modelBuilder.Entity< BaseEntity>() .Property(C => c.Id) .HasDatabaseGeneratedOption( DatabaseGeneratedOption.None); modelBuilder.Entity<人方式>()地图(M = GT; { m.MapInheritedProperties(); m.ToTable(人) ; }); modelBuilder.Entity<经营方式>()地图(M = GT; { m.MapInheritedProperties(); m.ToTable(业务) ; });
应用程序成功运行,但是当我回去的数据库,我觉得三(3)表,而不是两(2)我希望能够找到。有些测试会出现BaseEntity表创建,但从未使用过之后。一切似乎都工作得很好,这个空孤表除外。
我混乱与周围的DbModelBuilder配置,最终去掉它提供了预期的结果了BaseEntity配置;两(2)表中,他们每个人具有正确的属性和功能正常。
我最后一次测试中,撕裂了所有的DbModelBuilder配置,仅包含两个( 2)DbSet属性人和业务,并再次测试
公共DbSet<&人GT;人们{搞定;组; } 公共DbSet<商业与GT;企业{搞定;组; }要我吃惊的是项目建立,出去到数据库中,仅创建所有的两个表类的属性,包括从BaseEntity类继承的。我可以做的CRUD操作没有问题。
运行多项测试后,我无法找到最后的测试任何问题,我一直无法重现重复键错误这两篇文章警告。
对数据库的更改被成功提交,但在更新对象上下文时发生错误。 ObjectContext中可能处于不一致的状态。内部异常消息:AcceptChanges的不能继续,因为该对象的关键值与ObjectStateManager另一个对象发生冲突。确保键值调用的AcceptChanges之前是独一无二的。
我用马平类,但请不要介意。我解决这个问题是这样的:
公共类PersonMap:EntityTypeConfiguration<&人GT; {公众人物图() {地图(M = GT; {m.ToTable(人); m.MapInheritedProperties();}); HasKey(P => p.Id); 房产(P => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); } }
Remeber - 基类必须是抽象
In an effort to avoid the use of Table Per Hierarchy (TPH) I have been looking at examples of how best to implement Table-Per-Concrete Class (TPC) inheritance in my database model. I came across the official documentation and this article.
Below are some mock-up classes with some simple inheritance.
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; } }The DbModelBuilder configurations used per the examples in both articles.
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"); });The application runs successfully but when I go back to the database I find three (3) tables instead of the two (2) I expected to find. After a bit of testing it would appear the "BaseEntity" table is created but is never used. Everything seems to work just fine with the exception of this empty orphaned table.
I mess around with the DbModelBuilder configurations, eventually removing the "BaseEntity" configurations which provides the expected result; Two (2) tables, each of them having the correct properties and functioning correctly.
I do one last test, rip out all the DbModelBuilder configurations, only include the two (2) DbSet properties for "Person" and "Business" and test again.
public DbSet<Person> People { get; set; } public DbSet<Business> Businesses { get; set; }To my surprise the project builds, goes out to the database, creates only the two tables with all the class properties including the inherited ones from the "BaseEntity" class. I can do CRUD operations without issue.
After running many tests I can't find any issues with the final test and I have not been able to reproduce the duplicate key error both articles warned about.
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
解决方案
I use maping classes, but nevermind. I solve it like this:
public class PersonMap : EntityTypeConfiguration<Person> { public Person Map() { Map(m => { m.ToTable("Person"); m.MapInheritedProperties(); }); HasKey(p => p.Id); Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); } }Remeber - base class must be abstract.
更多推荐
表每个具体类型(TPC)的实体框架6继承(EF6)
发布评论