EntityFramework6.X 之Inheritance Stategy

Inheritance Stategy

1)      将实体类型的CLR属性映射到数据库中的多个表(实体拆分)

实体拆分允许一个实体类型的属性分散在多个表中,如Department实体类拆分到两个表中:Department(表里存放DepartmentID和Name字段)和DepartmentDetails(表里存放DepartmentID\Administrator\StartDate\Budget字段),通过多次调用Map方法将一部分属性映射到特定表

Eg: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");});

2)      将多个实体类型映射到数据库中的一个表(表拆分)

将使用同一个主键的两个实体类型映射到同一个表,其InstructorID为两个实体类型的共同主键,Instructor实体类型为主类型,且在该表中存在OfficeAssignment导航属性;OfficeAssignment实体类型中存在Instructor导航属性

Eg: 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");

3)      Table per hierarchy(TPH):映射”每个层次结构一张表”继承

EF默认的继承策略,继承层次结构中的所有类型都将映射到同一个表,鉴别器列用于标识每行的类型。默认情况下,鉴别器列将添加到名为”Discirminator”的表且层次结构中每个类型的CLR类型名称将用作鉴别器值,通常鉴别器用来鉴别不同的衍生了类。但是在查询操作的时候依然不影响查询,同样是采用类名进行查询,只是存储结构上发生了变化。

 

 

温馨提示:因TPH中所有属性存储在一张数据表中,就有可能出现在A派生类的属性Property1可以为空,而B派生类存储的时候不可以为空

根据上述图标显示当同一个属性在不同的继承类中所有约定不同时,

如下示例OnsiteCourse继承自Course,即Course是OnnsiteCourse的基类

Eg:modelBuilder.Entity<Course>().Map<Course>(m=>m.Requires("Type").HasValue("Course")).Map<OnsiteCourse>(m=>m.Requires("Type").HasValue("OnsiteCourse"));

4)       Talbe per Type(TPT):映射”每个类型一张表”继承

TPT是代表继承关系用过外键属性来关联,基类和派生类分别映射到不同的单独表,仅属于某个基类型或派生类型的属性存储在映射到该类型的一个表中,映射到派生类型的表还会存储一个将派生表与基表连接的外键。

 

 

同样我们可以创建上图的类:

 

实现多态关联:比如在User实体类中定义billinginfo属性,该属性是BillingDetail类型,但是是它的派生类如下图:

 

上述BillingInfo可以存储BillingDetail的任何一个派生类

 

 

5)      Table per Concrete Class(TPC):映射”每个具体类一张表”继承

在TPC映射情形下层次结构中的所有非抽象类型分别映射到具体的一张表,每个具体类中的表中都包含了抽象类的继承属性。抽象类与具体类在映射成数据表的时候并没有任何联系,调用MapInheritedProperties方法配置每个派生类型,TPC继承层次结构中表并不一定使用同一个主键,因此若让数据库生成的值具有相同标示,在插入中就会产生重复,所以一般指定不同的初始种子值或关闭主键属性的标示。

Eg: modelBuilder.Entity<Course>().Property(c => c.CourseID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

modelBuilder.Entity<OnsiteCourse>().Map(m =>{ m.MapInheritedProperties(); m.ToTable("OnsiteCourse"); });

modelBuilder.Entity<OnlineCourse>().Map(m => { m.MapInheritedProperties(); m.ToTable("OnlineCourse"); });

注释:Course是基类,OnsiteCourse类和OnlineCourse类都继承了Course类。分别存储成三张表。派生类中的表包含了基类表中的属性列。

例如下图中表示一个继承的类图,而映射的表格如下:

 

 

 

 

posted @ 2017-05-23 09:40  Terrence_Sun  阅读(207)  评论(0编辑  收藏  举报