EntityFramework Code-First 简易教程(四)-------继承策略

在前篇CodeFirst类型约定中,我们在数据库中为每一个模型类创建一个表,但是有个问题,我们可以设计出带继承关系的模型类,即面向对象编程既有“has a”(表示类继承)也有“is a”(表示类包含)关系,但是SQL的基础关系模型在表与表中仅支持"has a"关系,SQL数据库管理系统不支持继承类型。所以,怎样用关系型数据库来映射面向对象模型呢?

Code-First中有下面三种不同的方法来表示一个继承的层次结构:

  • Table per Hierarchy (TPH): 这种方法建议用一张表来表示继承层次结构,即这张表里包含了两个有继承关系类的鉴别列。看如下代码
public abstract class BillingDetail 
{
    public int BillingDetailId { get; set; }
    public string Owner { get; set; }        
    public string Number { get; set; }
}
 
public class BankAccount : BillingDetail
{
    public string BankName { get; set; }
    public string Swift { get; set; }
}
 
public class CreditCard : BillingDetail
{
    public int CardType { get; set; }                
    public string ExpiryMonth { get; set; }
    public string ExpiryYear { get; set; }
}
 
public class InheritanceMappingContext : DbContext
{
    public DbSet<BillingDetail> BillingDetails { get; set; }
}
View Code

 

 BankAccount类和CreaditCard类都继承于BillingDetail,在数据库中会生成如下表:

 在EF中这是默认的继承映射层级结构

 

  • Table per Type (TPT): 这个方法建议为每一个模型类写一个分离的表。如下图所示:

代码如下:

public abstract class BillingDetail
{
    public int BillingDetailId { get; set; }
    public string Owner { get; set; }
    public string Number { get; set; }
}
 
[Table("BankAccounts")]
public class BankAccount : BillingDetail
{
    public string BankName { get; set; }
    public string Swift { get; set; }
}
 
[Table("CreditCards")]
public class CreditCard : BillingDetail
{
    public int CardType { get; set; }
    public string ExpiryMonth { get; set; }
    public string ExpiryYear { get; set; }
}
 
public class InheritanceMappingContext : DbContext
{
    public DbSet<BillingDetail> BillingDetails { get; set; }
}
View Code

 

 

  • Table per Concrete class (TPC): 这个方法建议除了抽象类,一个实体类对应一个表。所以,如果有多个实体类继承于抽象类,抽象属性将会成为每个实体类对应的表的一部分。如下图:

代码:

public abstract class BillingDetail
{
    public int BillingDetailId { get; set; }
    public string Owner { get; set; }
    public string Number { get; set; }
}
        
public class BankAccount : BillingDetail
{
    public string BankName { get; set; }
    public string Swift { get; set; }
}
        
public class CreditCard : BillingDetail
{
    public int CardType { get; set; }
    public string ExpiryMonth { get; set; }
    public string ExpiryYear { get; set; }
}
    
public class InheritanceMappingContext : DbContext
{
    public DbSet<BillingDetail> BillingDetails { get; set; }
        
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BankAccount>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("BankAccounts");
        });
 
        modelBuilder.Entity<CreditCard>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("CreditCards");
        });            
    }
}
View Code

 

上面说的比较简单,如果想要了解更多详细信息,点击下面的是三个链接:

  1. Inheritance with EF Code First: Table per Hierarchy (TPH)
  2. Inheritance with EF Code First: Table per Type (TPT)
  3. Inheritance with EF Code First: Table per Concrete class (TPC)

 

总结:这一节我也看得一知半解,如果有大神肯指点迷津,不胜感激。

posted @ 2016-05-14 19:28  唐大兵  阅读(1712)  评论(0编辑  收藏  举报