继承映射策略的三种策略

There are following three different approaches to represent an inheritance hierarchy in Code First:

  1. Table per Hierarchy (TPH): This approach suggests one table for entire class inheritance hierarchy. Table includes discriminator column which distinguish between inheritance classes. This is a default inheritance mapping strategy in Entity Framework.
  2. Table per Type (TPT): This approach suggests seperate table for each domain class.
  3. Table per Concrete class (TPC): This approach suggests one table for one concrete class, but not for the abstract class. So if you inherit the abstract class in multiple concrete classes then the properties of the abstract class will be part of each table of concrete class.

Code First 有以下三种不同的方法来表示继承层次结构:

  1. 每个层次结构一张表 (TPH): 这种方法表明,为整个类继承层次结构一个表。表包括鉴别器列(discriminator )的区分继承类。这是在实体框架中的默认继承映射策略。
  2. 每个类型一张表 (TPT): 这种方法显示单独的表中为每个域类。
  3. 每个具体类 一张表(TPC) : 这种方法显示一个表为一个具体的类,而不是抽象类。因此如果你继承的抽象类在多个具体的类然后抽象类的属性中将每个表具体类的一部分。

 

----------------------------------------------------------------------------

 

---------------------------------------------------

 

三种策略的适用场景

I want to emphasize that there is no one single "best strategy fits all scenarios" exists. As you saw, each of the approaches have their own advantages and drawbacks. Here are some rules of thumb to identify the best strategy in a particular scenario:

  1. If you don’t require polymorphic associations or queries, lean toward TPC—in other words, if you never or rarely query for BillingDetails and you have no class that has an association to BillingDetail base class. I recommend TPC (only) for the top level of your class hierarchy, where polymorphism isn’t usually required, and when modification of the base class in the future is unlikely.
  2. If you do require polymorphic associations or queries, and subclasses declare relatively few properties (particularly if the main difference between subclasses is in their behavior), lean toward TPH. Your goal is to minimize the number of nullable columns and to convince yourself (and your DBA) that a denormalized schema won’t create problems in the long run.
  3. If you do require polymorphic associations or queries, and subclasses declare many properties (subclasses differ mainly by the data they hold), lean toward TPT. Or, depending on the width and depth of your inheritance hierarchy and the possible cost of joins versus unions, use TPC.

By default, choose TPH only for simple problems. For more complex cases (or when you’re overruled by a data modeler insisting on the importance of nullability constraints and normalization), you should consider the TPT strategy. But at that point, ask yourself whether it may not be better to remodel inheritance as delegation in the object model (delegation is a way of making composition as powerful for reuse as inheritance). Complex inheritance is often best avoided for all sorts of reasons unrelated to persistence or ORM. EF acts as a buffer between the domain and relational models, but that doesn’t mean you can ignore persistence concerns when designing your classes.

 

我想强调的是没有一单"最佳策略适合所有场景"存在。正如你所看到的每个方法有自己的优点和缺点。以下是一些经验法则来确定在特定的情况下最好的策略:

  1. 如果你不需要多态关联或查询,倾向于 TPC — — 换句话说,如果你从来没有或很少查询 BillingDetails 和你没有类关联 BillingDetail 基类。我推荐 TPC (仅限于) 您的类层次结构的顶层多态性并不是经常需要的而且将来也不太可能修改基类。
  2. 如果您需要多态关联或查询,并子类相对定义了几个属性 (特别是如果子类之间的主要区别是在他们的行为),倾向于 TPH。你的目标是尽量减少的可以为 null 的列数,并说服自己 (和您的 DBA) 非规范化的架构在长期内不会产生问题。
  3. 如果您需要使用多态关联或查询,并且子类(主要由它们拥有的数据不同的子类)定义了很多属性,倾向于 TPT。或者,如果考虑到继承层次结构的宽度和深度和Joins与Unions的可能产生的成本,使用 TPC。

默认情况下,选择 TPH 仅为简单的问题。对于更复杂的情况下 (或当你正在推翻由数据建模者坚持的为空性约束和归一化的重要性),你应该考虑 TPT 战略。但在这一点上,问一问自己,是否它可以用delegation 修改下对象模型中的继承 (代表团是作文一样强大的复用作为继承的一种方式)。复杂的继承通常最好能够通过许多与持久化或 ORM 无关的原因避免。虽然EF 充当域和关系模型之间的缓冲,但这并不意味着设计您的类时,您可以忽略关注持久化的内容。

参考

  1. Inheritance with EF Code First: Table per Hierarchy (TPH)
  2. Inheritance with EF Code First: Table per Type (TPT)
  3. Inheritance with EF Code First: Table per Concrete class (TPC)

EF继承关系映射的更多相关文章

  1. 在Entity Framework 中实现继承关系映射到数据库表

    继承关系映射到数据库表中有多种方式: 第一种:TPH(table-per-hiaerachy) 每一层次一张表 (只有一张表) 仅使用名为父类的类型名的一张表,它包含了各个子类的所有属性信息,使用区分 ...

  2. EF中关系映射问题

    一对一,和一对多的简单问题就部说了,直接来多对多这样的问题吧. 首现关系映射为这样的: /// <summary> /// 对应数据库中dbo.Address表 /// </summ ...

  3. entityframework学习笔记--007-实体数据建模基础之继承关系映射TPT

    Table per Type Inheritance (TPT)建模 1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表.Retail表有1:0...1 ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (8) -----第二章 实体数据建模基础之继承关系映射TPT

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-8 Table per Type Inheritance 建模 问题 你有这样一 ...

  5. entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH

    Table per Hierarchy Inheritance 建模 1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (9) -----第二章 实体数据建模基础之继承关系映射TPH

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-10 Table per Hierarchy Inheritance 建模 问题 ...

  7. Hibernate之实体关系映射

    延迟加载与即时加载 例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才 ...

  8. C# 数据操作系列 - 6 EF Core 配置映射关系

    0. 前言 在<C# 数据操作系列 - 5. EF Core 入门>篇中,我们简单的通过两个类演示了一下EF增删改查等功能.细心的小伙伴可能看了生成的DDL SQL 语句,在里面发现了些端 ...

  9. hibernate映射的 关联关系:有 一对多关联关系,一对一关联关系,多对多关联关系,继承关系

    hibernate环境配置:导包.... 单向n-1:单向 n-1 关联只需从 n 的一端可以访问 1 的一端 <many-to-one> 元素来映射组成关系: name: 设定待映射的持 ...

随机推荐

  1. 用NPOI从DataBase到Excel

    NPOI的C# Helper代码 public static void WriteExcel(DataTable dt, string filePath) { ) { HSSFWorkbook wk ...

  2. iOS学习笔记——键盘处理

    在网上找到的资料比较零散,这部分学起来感觉也有点空虚,内容就只包括隐藏键盘和键盘高度两部分 隐藏键盘其实就在我学习iOS开发的第一个程序里面已经实践过了,不过当时还懵懵懂懂,现在就了解了是什么一回事, ...

  3. Devexpress RaisePropertyChanged

    所有的重载设置字段作为参数传递到指定的值,而属性提高INotifyPropertyChanged.PropertyChanged事件. 如果一个字段已经成功地改变,setProperty方法中返回真. ...

  4. php 数组动态添加实现代码(最土团购系统的价格排序)

    最近在实现最土团购系统的价格排序功能,需要对$oc数组进行扩展,经过测试用下面的方法即可. 核心代码如下: <?php $now=time(); $oc = array( 'team_type' ...

  5. 爱上MVC~图表的使用Chart

    回到目录 图表在一个系统中是必须的,MVC架构把它当然是一个扩展集成了进来,通过简单的几句话就可以生成一个风格多样的图表,这给报表的开发带来了很大的方便,大叔的项目中也做了一个测试,把主要的代码贴出来 ...

  6. SharePoint 列表的导出导入

    有一群友问到关于 SharePoint 列表的导入与导出的问题,而最近也要做相关操作且好久没写博客了,所以记录下来,过程其实相当简单. 方法:将 列表 保存为 模板(可包含数据),下载模板文件,上传到 ...

  7. C#文件或文件夹压缩和解压方法(通过ICSharpCode.SharpZipLib.dll)

    我在网上收集一下文件的压缩和解压的方法,是通过ICSharpCode.SharpZipLib.dll 来实现的 一.介绍的目录 第一步:下载压缩和解压的 ICSharpCode.SharpZipLib ...

  8. css中定位

    一切皆为框div.h1或p元素尝尝被称为块级元素.这意味着这些元素显示为一块内容,即“块框”.与之相反,span和strong等元素称为“称为”行内元素“,这是因为他们的内容显示在行中,即”行内框“. ...

  9. ProxyPattern

    代理模式是aop编程的基础,其主要作用是操作对象,并将你需要的新功能切入若干个你想要的切入点,静态代理模式比较简单,但是缺点比较大,这里就不上代码了,下面写上动态代理模式的代码(jdk方式,而不是采用 ...

  10. Hibernate @OneToMany等注解设置查询过滤条件等

    1.如实体PdOrg对象中有users对象,数据库user表有字段DEL_FLAG(0:删除:1:未删除): private List<User> users= new ArrayList ...