• 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)

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

  • 相关阅读:
    youtube-VisualSfM and MeshLab workflow video-meshlab part integration
    testing_lab1
    homework2-st
    homework1-spm
    homework1-st
    just one last blog
    week 10
    week 9
    week 8
    课后题7
  • 原文地址:https://www.cnblogs.com/tang-tang/p/5493165.html
Copyright © 2020-2023  润新知