Table per Hierarchy Inheritance 建模

1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees的行。列EmployeeType作为鉴别列,鉴别这两种员工类型的行。 当EmployeType为1时,这一行代表一个专职员工(salaried or full-time employee),当值为2时,这一行代码一个钟点工(hourly employee).

图8-1

2.右键你的项目,添加上图中的poco实体。如下:

[Table("Employee", Schema = "example8")]
public abstract class Employee
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmployeeId { get; protected set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

Employee

public class FullTimeEmployee : Employee
{
public decimal? Salary { get; set; }
}

FullTimeEmployee

public class HourlyEmployee : Employee
{
public decimal? Wage { get; set; }
}

HourlyEmployee

3.创建一个继承自DbContext的上下文对象EF6RecipesContext;

public class EF6RecipesContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public EF6RecipesContext()
: base("name=EF6CodeFirstRecipesContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Employee>()
.Map<FullTimeEmployee>(m => m.Requires("EmployeeType").HasValue())
.Map<HourlyEmployee>(m => m.Requires("EmployeeType").HasValue());//如果去掉这两个map,会发现程序也能正常运行,并且在Employee表中生成了一个额外属性“Discriminator”
}
}

4.测试代码:

 using (var context = new EF6RecipesContext())
{
var fte = new FullTimeEmployee
{
FirstName = "Jane",
LastName = "Doe",
Salary = 71500M
};
context.Employees.Add(fte);
fte = new FullTimeEmployee
{
FirstName = "John",
LastName = "Smith",
Salary = 62500M
};
context.Employees.Add(fte);
var hourly = new HourlyEmployee
{
FirstName = "Tom",
LastName = "Jones",
Wage = 8.75M
};
context.Employees.Add(hourly);
context.SaveChanges();
}
using (var context = new EF6RecipesContext())
{
Console.WriteLine("--- All Employees ---");
foreach (var emp in context.Employees)
{
bool fullTime = emp is HourlyEmployee ? false : true;
Console.WriteLine("{0} {1} ({2})", emp.FirstName, emp.LastName,
fullTime ? "Full Time" : "Hourly");
}
Console.WriteLine("--- Full Time ---");
foreach (var fte in context.Employees.OfType<FullTimeEmployee>())
{
Console.WriteLine("{0} {1}", fte.FirstName, fte.LastName);
}
Console.WriteLine("--- Hourly ---");
foreach (var hourly in context.Employees.OfType<HourlyEmployee>())
{
Console.WriteLine("{0} {1}", hourly.FirstName, hourly.LastName);
}
}

输出如下:

--- All Employees ---Jane Doe (Full Time)
John Smith (Full Time)
Tom Jones (Hourly)
--- Full Time ---Jane Doe
John Smith
--- Hourly ---Tom Jones 5.注意看步骤3中的注释,如果注释掉“OnModelCreating”中的内容,查询Employee生成的sql如下:
SELECT
[Extent1].[Discriminator] AS [Discriminator],
[Extent1].[EmployeeId] AS [EmployeeId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Salary] AS [Salary],
[Extent1].[Wage] AS [Wage]
FROM [example8].[Employee] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'FullTimeEmployee',N'HourlyEmployee')
其实“TPT”与“TPH”的关系可以简单的理解成,是否子类与父类映射到同一张表。“TPT”相对灵活,单查询时使用了join,性能自然而然会有稍微影响;“TPH” 它将整个继承类型存储在一张单独的表中,他解决了TPT中的join连接问题,并带来了好的性能。但牺牲了数据库的灵活性。

entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH的更多相关文章

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

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

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

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

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

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

  4. 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型

    第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (10) -----第二章 实体数据建模基础之两实体间Is-a和Has-a关系建模、嵌入值映射

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-11 两实体间Is-a和Has-a关系建模 问题 你有两张有Is-a和Has-a ...

  6. 《Entity Framework 6 Recipes》翻译系列 (5) -----第二章 实体数据建模基础之有载荷和无载荷的多对多关系建模

    2-3 无载荷(with NO Payload)的多对多关系建模 问题 在数据库中,存在通过一张链接表来关联两张表的情况.链接表仅包含连接两张表形成多对多关系的外键,你需要把这两张多对多关系的表导入到 ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (6) -----第二章 实体数据建模基础之使用Code First建模自引用关系

    2-5 使用Code First建模自引用关系 问题 你的数据库中一张自引用的表,你想使用Code First 将其建模成一个包含自关联的实体. 解决方案 我们假设你有如图2-14所示的数据库关系图的 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (7) -----第二章 实体数据建模基础之拆分实体到多表以及拆分表到多实体

    2-6 拆分实体到多表 问题 你有两张或是更多的表,他们共享一样的主键,你想将他们映射到一个单独的实体. 解决方案 让我们用图2-15所示的两张表来演示这种情况. 图 2-15,两张表,Prodeuc ...

  9. 《Entity Framework 6 Recipes》翻译系列 (4) -----第二章 实体数据建模基础之从已存在的数据库创建模型

    不知道对EF感兴趣的并不多,还是我翻译有问题(如果是,恳请你指正),通过前几篇的反馈,阅读这个系列的人不多.不要这事到最后成了吃不讨好的事就麻烦了,废话就到这里,直奔主题. 2-2 从已存在的数据库创 ...

随机推荐

  1. Android之解析XML

    1.XML:可扩展标记语言. 可扩展标记语言是一种很像超文本标记语言的标记语言. 它的设计宗旨是传输数据,而不是显示数据. 它的标记没有被预定义.需要自行定义标签. 它被设计为具有自我描述性. 是W3 ...

  2. 项目管理_FindBugs的使用

    本章将讲述如何在Myeclipse下,使用FindBugs,静态分析工具,无需开发人员费劲就能找出代码中已有的缺陷. 一:Myeclipse下如何安装FindBugs插件 1:FindBugs插件下载 ...

  3. SQL Server中SELECT会真的阻塞SELECT吗?

    在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...

  4. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...

  5. 分享MSSQL、MySql、Oracle的大数据批量导入方法及编程手法细节

    1:MSSQL SQL语法篇: BULK INSERT [ database_name . [ schema_name ] . | schema_name . ] [ table_name | vie ...

  6. Android(2)—Mono For Android App版本自动更新

    0.前言 公司Android查询的项目已经开始,整体采用Java后台+App前台来实现,由于项目小,App这块就我一个人开发,首先需要研究的是:Android版本的更新升级问题:本人经过近一周的学习整 ...

  7. 续 CentOS7(mini) 运行MVC5 + Mariadb

    上一篇,介绍了在CentOS7上使用mono官方二进制安装包快速安装mono环境 并且成功运行了一个Owin自宿主应用(Booker) 由于Owin自宿主应用不需要System.Web的支持,所以可以 ...

  8. [PHP源码阅读]empty和isset函数

    近日被问到PHP中empty和isset函数时怎么判断变量的,刚开始我是一脸懵逼的,因为我自己也只是一知半解,为了弄懂其真正的原理,赶紧翻开源码研究研究.经过分析可发现两个函数调用的都是同一个函数,因 ...

  9. [Java Collection]List分组之简单应用.

    前言 今天有一个新需求, 是对一个List进行分组, 于是便百度到一些可用的代码以及我们项目使用的一些tools, 在这里总结下方便以后查阅. 一: 需求 现在我们一个数据库表t_series_val ...

  10. salesforce 零基础学习(六十)Wizard样式创建数据

    项目中表之间关联关系特别多,比如三个表中A,B,C  C作为主表,A,B作为从表,有时候C表需要创建数据时,同时需要创建A,B两个表的数据,这种情况下,使用Wizard样式会更加友好. 以Goods_ ...