首页 > 其他分享 >EF7继承映射

EF7继承映射

时间:2023-03-05 17:57:38浏览次数:44  
标签:映射 继承 子类 基类 EF7 Animal 表中

Entity Framework 7 (EF7)中的继承映射允许您将类层次结构映射到数据库中的表层次结构。具体而言,这意味着您可以创建一个基类,然后从该基类派生多个子类,并将这些子类映射到不同的数据库表。这使得在数据库中存储不同类型的数据变得更加方便,同时还能保持面向对象编程的优雅性。
EF7提供了三种类型的继承映射:单表继承(Table Per Hierarchy,TPH)、分层表继承(Table Per Type,TPT)和单独的表继承(Table Per Concrete Class,TPC)。下面分别介绍这三种映射类型。
性能基准

单表继承映射(Table Per Hierarchy,TPH)

单表继承映射将整个类层次结构映射到单个数据库表中。每个类在表中对应一行,其中包括一个用于区分不同子类的Discriminator列。例如,考虑以下类层次结构:

public abstract class Animal
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

public class Dog : Animal
{
    public string Breed { get; set; }
}

public class Cat : Animal
{
    public bool IsIndoor { get; set; }
}

使用单表继承映射,可以将这个类层次结构映射到以下数据库表:

+----+-------+-----+-------+------------+------------+
| Id | Name  | Age | Breed | IsIndoor   | Discriminator |
+----+-------+-----+-------+------------+------------+
| 1  | Fido  | 3   | Poodle| NULL       | Dog          |
+----+-------+-----+-------+------------+------------+
| 2  | Felix | 5   | NULL  | true       | Cat          |
+----+-------+-----+-------+------------+------------+

可以看到,每个Animal子类都在同一个表中表示为一行,并使用Discriminator列进行区分。
要使用TPH映射,在EF7中,可以使用Fluent API进行配置,如下所示:

modelBuilder.Entity<Animal>()
    .HasDiscriminator<string>("Discriminator")
    .HasValue<Dog>("Dog")
    .HasValue<Cat>("Cat");

这个代码片段将Animal类设置为基类,然后使用HasDiscriminator方法指定Discriminator列的名称。接下来,使用HasValue方法为每个Animal子类指定一个值,以便在Discriminator列中进行区分。

分层表继承映射(Table Per Type,TPT)

分层表继承映射将基类和每个子类映射到不同的数据库表中。每个子类的表都包含基类的所有列和子类特有的列。例如,对于上述类层次结构,使用分层表继承映射,可以将Animal、Dog和Cat分别映射到三个不同的表中:

Animal table:
+----+-------+-----+
| Id | Name  | Age |
+----+-------+-----+
| 1  | Fido  | 3   |
+----+-------+-----+
| 2  | Felix | 5   |
+----+-------+-----+

Dog table:
+----+-------+-----+-------+
| Id | Name  | Age | Breed |
+----+-------+-----+-------+
| 1  | Fido  | 3   | Poodle|
+----+-------+-----+-------+

Cat table:
+----+-------+-----+----------+
| Id | Name  | Age | IsIndoor |
+----+-------+-----+----------+
| 2  | Felix | 5   | true     |
+----+-------+-----+----------+

可以看到,每个表都只包含基类和对应的子类的列。每个子类表还包含一个外键,指向基类表的主键。
要使用TPT映射,在EF7中,可以使用Fluent API进行配置,如下所示:

modelBuilder.Entity<Animal>()
    .ToTable("Animals");

modelBuilder.Entity<Dog>()
    .ToTable("Dogs")
    .HasOne(a => a.Animal)
    .WithOne()
    .HasForeignKey<Dog>(d => d.Id);

modelBuilder.Entity<Cat>()
    .ToTable("Cats")
    .HasOne(a => a.Animal)
    .WithOne()
    .HasForeignKey<Cat>(c => c.Id);

这个代码片段中,Animal被映射到Animals表中。对于每个Animal子类,使用ToTable方法将其映射到相应的表中。在每个子类表中,使用HasOne方法指定一个导航属性,表示它与基类表中的一行相关联。使用HasForeignKey方法指定外键属性和基类表中的主键。

单独的表继承映射(Table Per Concrete Class,TPC)

单独的表继承映射将每个类都映射到一个独立的数据库表中。每个表都只包含该类的列。这意味着基类和子类之间没有直接的关系。例如,对于上述类层次结构,使用单独的表继承映射,可以将Animal、Dog和Cat分别映射到三个不同的表中:

Animal table:
+----+-------+-----+
| Id | Name  | Age |
+----+-------+-----+
| 1  | Fido  | 3   |
+----+-------+-----+
| 2  | Felix | 5   |
+----+-------+-----+

Dog table:
+----+-------+-----+-------+
| Id | Name  | Age | Breed |
+----+-------+-----+-------+
| 1  | Fido  | 3   | Poodle|
+----+-------+-----+-------+
    
Cat table:
+----+-------+-----+----------+
| Id | Name  | Age | IsIndoor |
+----+-------+-----+----------+
| 2  | Felix | 5   | true     |
+----+-------+-----+----------+

要使用TPC映射,在EF7中,可以使用Fluent API进行配置,如下所示:

modelBuilder.Entity<Animal>()
    .ToTable("Animals");

modelBuilder.Entity<Dog>()
    .ToTable("Dogs");

modelBuilder.Entity<Cat>()
    .ToTable("Cats");

这个代码片段中,每个类都被映射到不同的表中,使用ToTable方法指定表名。

继承映射的查询

在EF7中,使用继承映射时,可以查询基类和子类的实例。例如,以下代码查询所有动物的名字:

using (var context = new AnimalContext())
{
    var names = context.Set<Animal>()
        .Select(a => a.Name)
        .ToList();
}

这个查询将返回Animal表和所有子类表中的所有名称。如果要只查询特定类型的动物,可以在查询中使用OfType方法,例如:

using (var context = new AnimalContext())
{
    var dogNames = context.Set<Animal>()
        .OfType<Dog>()
        .Select(d => d.Name)
        .ToList();
}

这个查询只返回Dog表中的名称。

总结

继承映射是一种重要的ORM技术,允许将类层次结构映射到数据库表层次结构中。EF7支持三种继承映射策略:分层表继承映射、单独的表继承映射和联合表继承映射。使用Fluent API可以很容易地配置这些映射。在查询数据时,可以使用OfType方法筛选出特定类型的实例。

标签:映射,继承,子类,基类,EF7,Animal,表中
From: https://www.cnblogs.com/YataoFeng/p/17181056.html

相关文章

  • 关于 Javascript 的几种继承
    原型链的概念:原型链通俗易懂的理解就是可以把它想象成一个链条,互相连接构成一整串链子而原型链中就是实例对象和原型对象之间的链接每个函数都有一个prototype属性,这个p......
  • 4.理解es6 class构造以及继承的底层实现原理
    javascript使用的是原型式继承,我们可以通过原型的特性实现类的继承,es6为我们提供了像面向对象继承一样的语法糖。1.类的实现class底层仍然是构造函数调用_classCallChe......
  • 实现js继承的几种方式以及他们的优缺点
    7.实现继承的几种方式以及他们的优缺点①类式继承(构造函数) varfather=function(){  this.age=52;  this.say=function(){   alert('helloiam'......
  • 继承中构造方法的访问特点
    1.子类中所有的构造方法都会默认会访问父类中的无参构造方法 2.每个子类的构造方法的第一句默认是:super()3.因为子类会继承父类中的数据,可能还会使用父类中的数据,所以子......
  • mybatis处理一对多的映射关系
    实体类packageorg.example.entity;importjava.util.List;publicclassDept{privateIntegerdeptId;privateStringdeptName;privateList<Emp>......
  • 设置静态资源映射
    静态页面要么修改默认访问静态资源路径,要么将他们放在templates或static包下如何设置静态资源映射?@ConfigurationpublicclassWebMvcConfigextendsWebMvcConfigurat......
  • Python教程:类的继承,什么是继承
    一、什么是继承继承是一种新建类的方式,新建的类称为子类,被继承的类称为父类继承的特性是:子类会遗传父类的属性继承是类与类之间的关系二、为什么用继承使用继承可以......
  • 内存映射
    介绍#include<sys/mman.h>void*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_toffset);功能:将文件映射到内存中参数:addr:允许......
  • Shader入门精要笔记 - CH10.1_环境映射之折射
    折射:光线从一种介质进入另一种介质,传播方向会发生改变  Cubemap是在Teapot_Refract的位置拍摄的Shader"My/Tex2/RefractCubeMap"{Properties{......
  • day07-MyBatis的关联映射01
    MyBatis的关联映射Mybatis的关联映射实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。针对多表之间的操作,MyBatis提......