Code First TPH、TPT、TPC与继承类
一、Table Per Hierarchy (TPH,默认)
每个层次结构共用一个表,类的每一个属性都必须是可空的。
1、默认行为
只建立一个表,把基类和子类中的所有属性都映射为表中的列。
在这种处理方式中,EF为基类和所有子类共建立一个表,基类和子类中的所有属性都映射为表中的一个列。t默认在这个表中建立一个叫做Discriminator的列,类型是nvarchar,长度是128。
在存储基类或子类的时候,把类名作为Discriminator列的值。
2、Fluent API修改默认行为
modelBuilder.Entity<Course>()
.Map<Course>(m => m.Requires("Type").HasValue("Course"))
.Map<OnsiteCourse>(m => m.Requires("Type").HasValue("OnsiteCourse"));
Map方法中传入的类型参数是子类的类名,Requires用于指定Discriminator列的名字,HasValue用于指定它的类型和每个子类对应的值。
二、Table Per Type(TPT)
每个类就各要一个表。
1、默认行为
为基类和每个子类各建立一个表,每个与子类对应的表中只包含子类特有的属性对应的列。
子类的表中只包含子类特有的属性,子表还会存储一个将子表与基表联接的外键。
2、Fluent API修改默认行为
我们可以使用Map方法强制让Code First使用TPT方式,因为Code First默认使用的是TPC方式。
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<OnsiteCourse>().ToTable("OnsiteCourse");
三、Table Per ConCrete Type(TPC)
不推荐使用。每个具体的派生类各一个表
1、默认行为
在子类对应的表中除了子类特有的属性外还有基类的属性对应的表。基类可以是abstract
2、Fluent API修改默认行为
通过MapInheritedProperties方法就可以强制Code First使用TPC方式。
modelBuilder.Entity<Course>()
.Property(c => c.CourseID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);--因为属于 TPC 继承层次结构的表并不使用同一个主键,
关闭主键属性的标识,避免为不同字表插入重复的实体键。 modelBuilder.Entity<OnsiteCourse>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("OnsiteCourse");
}); modelBuilder.Entity<OnlineCourse>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("OnlineCourse");
});
四、实体拆分
允许一个实体类型的属性分散在多个表中。
实体拆分通过多次调用 Map 方法将一部分属性映射到特定表。
在以下示例中,Department 实体拆分到两个表中:Department 和 DepartmentDetails。
modelBuilder.Entity<Department>() .Map(m =>
{
m.Properties(t => new { t.DepartmentID, t.Name });
m.ToTable("Department");
}).Map(m =>
{
m.Properties(t => new { t.DepartmentID, t.Administrator, t.StartDate, t.Budget });
m.ToTable("DepartmentDetails");
});
五、表拆分
两个实体类型映射到同一个表。
1.两个类必须共享同一个主键。
2.两个类之间的关系必须被映射为表之间的一对一关系。
modelBuilder.Entity<OfficeAssignment>().HasKey(t => t.InstructorID); --共用组件
modelBuilder.Entity<Instructor>() .HasRequired(t => t.OfficeAssignment).WithRequiredPrincipal(t => t.Instructor);--一对一关系
modelBuilder.Entity<Instructor>().ToTable("Instructor");
modelBuilder.Entity<OfficeAssignment>().ToTable("Instructor");
六、将类指定为复杂类型
1、指定方法:
DataAnnotations方式:[ConlexType]或FluentAPI:modelBuilder.ComplexType<Details>();
注意:
1.复杂类型类不能有主键。
2.复杂类型只能包含.net基础类型的属性。
3.使用复杂类型的类,只能包复杂类型的一个实例,不能使用复杂类型的集合。
2、配置复杂类型的属性
1、可以对 ComplexTypeConfiguration 调用 Property。
modelBuilder.ComplexType<Details>() .Property(t => t.Location).HasMaxLength(20);
或
public class AddressComplexTypeConfiguration:ComplexTypeConfiguration<Address>
{
public AddressComplexTypeConfiguration()
{
Property(a => a.Country).HasColumnName("Country").HasMaxLength();
Property(a => a.ZipCode).HasColumnName("ZipCode").HasMaxLength();
}
}
2、也可以使用点表示法访问复杂类型的属性。
modelBuilder.Entity<OnsiteCourse>().Property(t => t.Details.Location) .HasMaxLength();
七、DataBase初始化
1、调用Database.SetInitializer方法:
一般Global.ascx.cs,Main应用程序的入口等地方调用Database.SetInitializer方法:
- 只要Fluent API配置的数据库映射发生变化或者domain中的model发生变化了,就把以前的数据库删除掉,根据新的配置重新建立数据库。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());
- 只有在没有数据库的时候才会根据数据库连接配置创建新的数据库。这种配置主要用于production环境。
Database.SetInitializer(new CreateDatabaseIfNotExists<BreakAwayContext>());
- 不管数据库映射或者model是否发生变化,每次都重新删除并根据配置重建数据库。
Database.SetInitializer(new DropCreateDatabaseAlways<BreakAwayContext>());
2、通过配置文件更灵活的指定数据库初始化的方式:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="DatabaseInitializerForType OrderSystemContext" value="System.Data.Entity.DropCreateDatabaseIfModelChanges[[OrderSystemContext]], EntityFramework" />
</appSettings>
</configuration>
3、自定义数据库初始化类
通过自定的初始化类,还可以将一些基础数据在创建数据库之后插入到数据库中去。
public class DropCreateOrderDatabaseWithSeedValueAlways : DropCreateDatabaseAlways<OrderSystemContext>
{
protected override void Seed(OrderSystemContext context)
{
context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6400", Manufactory = "DELL", ListPrice = , NetPrice = });
context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6420", Manufactory = "DELL", ListPrice = , NetPrice = });
}
} Database.SetInitializer(new DropCreateOrderDatabaseWithSeedValueAlways());
Code First TPH、TPT、TPC与继承类的更多相关文章
- Code First 中的 TPH TPT TPC
public class Blog { public int Id { get; set; } public DateTime Creationdate { get; set; } public st ...
- C++浅析——继承类内存分布和虚析构函数
继承类研究 1. Code 1.1 Cbase, CTEST为基类,CTest2为其继承类,并重新申明了基类中的同名变量 class CBase { public: int Data; CBase() ...
- C#基础-事件 继承类无法直接引发基类的事件
An event can be raised only from the declaration space in which it is declared. Therefore, a class c ...
- IOS 杂笔-1(为什么不继承类簇?)
答:首先,类簇是可以继承的,并不是不可以.例如,我们可以选择继承NSSting,但是此时你用你自己设定的类去调用NSSting的一些方法时,会存在无法实现的问题,这是为什么呢. 1.类簇里有很多私有的 ...
- 虚函数列表: 取出方法 // 虚函数工作原理和(虚)继承类的内存占用大小计算 32位机器上 sizeof(void *) // 4byte
#include <iostream> using namespace std; class A { public: A(){} virtual void geta(){ cout < ...
- 使用Json.Net处理json序列化和反序列化接口或继承类
以前一直没有怎么关注过Newtonsoft的Json.Net这个第三方的.NET Json框架,主要是我以前在开发项目的时候大多数使用的都是.NET自带的Json序列化类JavaScriptSeria ...
- java 继承类与接口问题
java 先extends 继承类,再implements 继承接口 public class DataBase extends ClassBase implements Ijiekou { }// ...
- 【整理】C++虚函数及其继承、虚继承类大小
参考文章: http://blog.chinaunix.net/uid-25132162-id-1564955.html http://blog.csdn.net/haoel/article/deta ...
- QEvent整理归纳:140种类型,29个继承类,7个函数,3种事件来源
140种事件类型: QEvent::None QEvent::AccessibilityDescription QEvent::AccessibilityHelp QEvent::Accessibil ...
随机推荐
- 【C语言】-指针和字符串
本文目录 字符串回顾 一.用指针遍历字符串的所有字符 二.用指针直接指向字符串 三.指针处理字符串的注意 说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速 ...
- Hibernate项目环境搭建
1.首先在eclipse里面新建一个Java工程. 2.在数据库中新建一个数据库(无需创建表,有Hibernate生成). 3.在项目中导入Hibernate所依赖的jar包,该jar包可以在此下载: ...
- Java ee 之 html/css样式复习
内容: 1,html/css样式 2,模拟简书注册登陆页面 *重点: 1,width:auto;height:auto; 2,background-image:url(Q5.png);left top ...
- 记一个bug的排查过程---复盘
公众号做了新需求:菜单的click事件,支持多条客服消息. 上线后,只有一个功能不好使,是点击菜单,预期发一条文本类型的客服消息. 实际操作时,点这个菜单项后,什么也没有发生. elk上看日志,也没有 ...
- Firebird execute block 批处理
火鸟的批处理,效率好高,使用简单. execute block as declare variable i ; begin ) do begin :i = :i + ; insert into m_u ...
- MVVM - 事件转命令2
在使用MVVM模式时, 按照模式的规则是尽量不直接使用事件. 所以对于以前一直使用事件模式的同行来说确实有点头疼. 还好微软给我们提供了几种间接使用事件(命令)的方法, 下面我就来看看这几种方法: I ...
- jquery 使用整理机制
短路表达式 与 多重短路表达式 短路表达式这个应该人所皆知了.在 jQuery 中,大量的使用了短路表达式与多重短路表达式. 短路表达式:作为"&&"和" ...
- js 对象数据观察者实现
var observer = function (originalData) { var newData = {}; newData.observer = {}; newData.$data = {} ...
- PHP学习10——Cookie和Session技术
主要内容: Cookie技术 创建cookie 查看cookie 读取cookie 用cookie记录访问时间和次数 删除cookie cookie的生命周期 Session技术 session工作原 ...
- Redis实现主从复制(Master&Slave)
由于前段时间公司项目比较赶,一直抽不出时间写博客,今天偷空写一篇吧.前面给大家讲解了单机版redis的基本操作,现在继续给大家讲解一下Redis的进阶部分,主从复制和读写分离. 一.Master&am ...