学习教材:http://www.entityframeworktutorial.net/code-first/inheritance-strategy-in-code-first.aspx
学习目的:理解 TPH、TPT、TPC 的不同和实现方法。
其实实现方法都很简单,DataAnnotation 和 Fluent API 的使用而已。
实体是可继承的
实体映射到数据库中的表,这大家都明白。但是,数据库中的表虽然是平等的,在实际应用中的实体却是有层次关系的,此时我们很自然地需要实体间出现继承关系。
我们希望:基类包含该表的基本字段,派生类在其上增添特定的业务字段。
那么此时表结构的设计就有文章可做了。
Code First 允许使用继承,而且支持的很不错。
Table per Hierarchy (TPH)
在 TPH 中基类和派生类是映射到同一张表的多个实体,通过 Discriminator 字段(称为鉴别列)来识别数据源所对应的实体。
TPH 是 Code First 的默认约定。当你的实体出现继承关系时将自动添加到他们所映射的表结构中。
额外的,你也可以通过 Fluent API 修改实体鉴别列的字段名和填充值:
modelBuilder.Entity<Entity1>().Map(
m => {
m.Requires("FieldName").HasValue("Value1");
}
).Map<Entity2>(
m => {
m.Requires("FieldName").HasValue("Value2");
}
);
Table per Type (TPT)
当你希望将基类和派生类映射到不同的表,又希望派生类对应的表只包含该派生类增添的字段时,你所采用的设计风格就是 TPT。
Code First 允许你通过显式改变派生类的 [Table] 来实现该设计。此时基类的主键是派生类的外键。
Table per Concrete Type (TPC)
当你希望基类和派生类映射到不同的表,又希望派生类映射的表包含全部的字段,那么你所采用的设计风格就是 TPC。
你可以通过 Fluent API 来实现该风格:
modelBuilder.Entity<Entity1>().Map(
m => {
m.ToTable("Table1");
}
).Map<Entity2>(
m => {
m.ToTable("Table2");
m.MapInheritedProperties();
}
);
注意,此时 EF 不会主动为主键设置自增。
网友评论