实体框架中的每个具体类型(TPC)继承6(EF6) [英] Table Per Concrete Type (TPC) Inheritance in Entity Framework 6 (EF6)

查看:135
本文介绍了实体框架中的每个具体类型(TPC)继承6(EF6)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了避免使用Table Per Hierarchy(TPH),我一直在研究在数据库模型中如何最好地实现Table-Per-Concrete Class(TPC)继承的例子。我遇到了官方文档这篇文章



下面是一些类似于简单继承的模拟类。

  public class BaseEntity 
{
public BaseEntity()
{
ModifiedDateTime = DateTime.Now;
}

[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id {get;组; }

public DateTime ModifiedDateTime {get;组; }
}

public class Person:BaseEntity
{
public string FirstName {get;组; }
public string LastName {get;组;
}

public class Business:BaseEntity
{
public string Name {get;组; }
public string Location {get;组; }
}

这两篇文章中的示例都使用了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)个表,而不是我(二)我预计会找到。经过一点测试,它会出现BaseEntity表被创建,但从未使用过。除了这个空的孤立表之外,一切似乎都很好。



我混淆了DbModelBuilder配置,最终删除了提供预期结果的BaseEntity配置;两个(2)表,每个都具有正确的属性并正常工作。



我做了最后一个测试,将所有的DbModelBuilder配置,只包括两个2)Person和Business的DbSet属性并再次测试。

  public DbSet< Person>人{get;组; } 
public DbSet< Business>企业{get;组; }

令我惊讶的是项目构建了,出来到数据库,只创建了所有的两个表类属性包括从BaseEntity类继承的类属性。我可以在没有问题的情况下执行CRUD操作。



运行许多测试后,我无法找到最终测试的任何问题,我无法再现重复的键错误两个文章都提醒了。


数据库更改已成功提交,但在更新对象上下文时发生错误
。 ObjectContext可能是
在不一致的状态。内部异常消息:AcceptChanges
无法继续,因为对象的键值与ObjectStateManager中的另一个
对象冲突。确保在调用AcceptChanges之前键值是
唯一。





  1. 我很好奇为什么示例使用MapInheritedProperties属性;这是一个过时的方法吗?

  2. 为什么这两个例子都说包含BaseEntity的配置属性,但是包含BaseEntity类的DbSet属性或任何DbModelBuilder配置会导致未使用要创建的表。

  3. 关于文章警告的唯一键错误;我无法重现错误,我已经用主键测试了很多次,作为数据库生成的int和数据库生成的guid。关于这个错误的信息也已经过时了,还是有可以运行的测试来产生所述错误?


解决方案

我使用映射类,但是不要使用。我解决了这个问题:

  public class PersonMap:EntityTypeConfiguration< Person> 
{
public PersonMap()
{
Map(m => {m.ToTable(Person); 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.

  1. I am curious why the examples use the MapInheritedProperties property; is this an outdated method?
  2. Why do both examples say to include configuration properties for the "BaseEntity" yet including either the DbSet property or any DbModelBuilder configurations for the "BaseEntity" class causes an unused table to be created.
  3. In reference to the unique key error the articles warned of; I am unable to reproduce the error and I have tested many times with the primary key as either an int generated by the database and a guid generated by the database. Is the information about this error also obsolete or is there a test I can run to produce said error?

解决方案

I use maping classes, but nevermind. I solve it like this:

public class PersonMap : EntityTypeConfiguration<Person>
{
    public PersonMap()
    {
        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)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆