• entityframework学习笔记--008-实体数据建模基础之继承关系映射TPH


    Table per Hierarchy Inheritance 建模

    1.让我们假设你有如图8-1中的表,Employee表包含hourly employees 和salaried employees的行。列EmployeeType作为鉴别列,鉴别这两种员工类型的行。 当EmployeType为1时,这一行代表一个专职员工(salaried or full-time employee),当值为2时,这一行代码一个钟点工(hourly employee).

    图8-1

    2.右键你的项目,添加上图中的poco实体。如下:

    [Table("Employee", Schema = "example8")]
        public abstract class Employee
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int EmployeeId { get; protected set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }
    Employee
    public class FullTimeEmployee : Employee
        {
            public decimal? Salary { get; set; }
        }
    FullTimeEmployee
    public class HourlyEmployee : Employee
        {
            public decimal? Wage { get; set; }
        }
    HourlyEmployee

    3.创建一个继承自DbContext的上下文对象EF6RecipesContext;

    public class EF6RecipesContext : DbContext
        {
            public DbSet<Employee> Employees { get; set; }
            public EF6RecipesContext()
                : base("name=EF6CodeFirstRecipesContext")
            {
            }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Entity<Employee>()
                .Map<FullTimeEmployee>(m => m.Requires("EmployeeType").HasValue(1))
                .Map<HourlyEmployee>(m => m.Requires("EmployeeType").HasValue(2));//如果去掉这两个map,会发现程序也能正常运行,并且在Employee表中生成了一个额外属性“Discriminator”
            }
        }

    4.测试代码:

     1 using (var context = new EF6RecipesContext())
     2             {
     3                 var fte = new FullTimeEmployee
     4                 {
     5                     FirstName = "Jane",
     6                     LastName = "Doe",
     7                     Salary = 71500M
     8                 };
     9                 context.Employees.Add(fte);
    10                 fte = new FullTimeEmployee
    11                 {
    12                     FirstName = "John",
    13                     LastName = "Smith",
    14                     Salary = 62500M
    15                 };
    16                 context.Employees.Add(fte);
    17                 var hourly = new HourlyEmployee
    18                 {
    19                     FirstName = "Tom",
    20                     LastName = "Jones",
    21                     Wage = 8.75M
    22                 };
    23                 context.Employees.Add(hourly);
    24                 context.SaveChanges();
    25             }
    26             using (var context = new EF6RecipesContext())
    27             {
    28                 Console.WriteLine("--- All Employees ---");
    29                 foreach (var emp in context.Employees)
    30                 {
    31                     bool fullTime = emp is HourlyEmployee ? false : true;
    32                     Console.WriteLine("{0} {1} ({2})", emp.FirstName, emp.LastName,
    33                     fullTime ? "Full Time" : "Hourly");
    34                 }
    35                 Console.WriteLine("--- Full Time ---");
    36                 foreach (var fte in context.Employees.OfType<FullTimeEmployee>())
    37                 {
    38                     Console.WriteLine("{0} {1}", fte.FirstName, fte.LastName);
    39                 }
    40                 Console.WriteLine("--- Hourly ---");
    41                 foreach (var hourly in context.Employees.OfType<HourlyEmployee>())
    42                 {
    43                     Console.WriteLine("{0} {1}", hourly.FirstName, hourly.LastName);
    44                 }
    45             }
    View Code

    输出如下:

    --- All Employees ---Jane Doe (Full Time)
    John Smith (Full Time)
    Tom Jones (Hourly)
    --- Full Time ---Jane Doe
    John Smith
    --- Hourly ---Tom Jones

    5.注意看步骤3中的注释,如果注释掉“OnModelCreating”中的内容,查询Employee生成的sql如下:
    SELECT 
        [Extent1].[Discriminator] AS [Discriminator], 
        [Extent1].[EmployeeId] AS [EmployeeId], 
        [Extent1].[FirstName] AS [FirstName], 
        [Extent1].[LastName] AS [LastName], 
        [Extent1].[Salary] AS [Salary], 
        [Extent1].[Wage] AS [Wage]
        FROM [example8].[Employee] AS [Extent1]
        WHERE [Extent1].[Discriminator] IN (N'FullTimeEmployee',N'HourlyEmployee')
    其实“TPT”与“TPH”的关系可以简单的理解成,是否子类与父类映射到同一张表。“TPT”相对灵活,单查询时使用了join,性能自然而然会有稍微影响;“TPH” 它将整个继承类型存储在一张单独的表中,他解决了TPT中的join连接问题,并带来了好的性能。但牺牲了数据库的灵活性。
  • 相关阅读:
    java
    java
    java
    java
    java
    java
    java
    java
    sed命令的用法
    linux系统产生随机数的6种方法
  • 原文地址:https://www.cnblogs.com/renjing/p/6138721.html
Copyright © 2020-2023  润新知