×

EntityFramework Code First 的三种实体继承策略

96
傅易君
2016.04.08 15:13* 字数 512

学习教材: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 不会主动为主键设置自增。

ASP.NET 实战
Web note ad 1