📅  最后修改于: 2023-12-03 15:14:52.831000             🧑  作者: Mango
在 Entity Framework 中,继承是一个常见的模式,它允许从一个模型中创建出另一个模型,并且使继承的模型能够自动继承基本模型的属性和行为。本文将介绍 Entity Framework 中的继承模式,并提供一些示例。
Table per Hierarchy(TPH)是最常见的 EF 继承模式之一。此模式使用单个表来存储层次结构中的所有实体,并区分它们的类型。每个实体类型都有一个标识列,该列用于区分层次结构中的不同实体类型。例如,我们有一个动物的继承层次结构,其中有四个类:Animal、Dog、Cat 和 Bird。
从 Animal 类派生的类,将 Animal 类和 Dog 类作为同一张表,在表中创建了一个 Name 列和一个 AnimalType 列,AnimalType 列指示着每一行数据属于哪种实体类型。其中,AnimalType 的值可以使用枚举来表示。下面是一个示例:
public enum AnimalType
{
Animal = 0,
Dog = 1,
Cat = 2,
Bird = 3
}
public class Animal
{
public int Id { get; set; }
public string Name { get; set; }
public AnimalType AnimalType { get; set; }
}
public class Dog : Animal
{
public string Breed { get; set; }
}
public class Cat : Animal
{
public bool IsLazy { get; set; }
}
public class Bird : Animal
{
public int WingSpan { get; set; }
}
在这个例子中,我们定义了一个用于表示 AnimalType 列的枚举。Animal 类是一个抽象类,有一个 AnimalType 属性,用于区分继承结构中的不同实体类型。Dog、Cat 和 Bird 从 Animal 类继承而来,并为每个实体类型添加了一个属性。
现在,我们需要将这些类映射到一个单独的表中,用于实现 Table per Hierarchy:
public class AnimalContext : DbContext
{
public DbSet<Animal> Animals { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Animal>()
.Map<Dog>(m => m.Requires("AnimalType").HasValue((int)AnimalType.Dog))
.Map<Cat>(m => m.Requires("AnimalType").HasValue((int)AnimalType.Cat))
.Map<Bird>(m => m.Requires("AnimalType").HasValue((int)AnimalType.Bird));
base.OnModelCreating(modelBuilder);
}
}
在模型构建器中,我们可以使用 Map 方法映射 Animal 类型,将其映射到数据库中的单个表。在 Map 方法中,我们使用 Requires 方法为每个类型指定一个特定的 AnimalType 值。
现在,我们可以通过 AnimalContext 上下文对象查询和保存动物的不同类型。
Table per Type(TPT) 是另一个常见的 EF 继承模式。此模式也使用多个表来存储层次结构中的实体,但不同之处在于每个实体类型都有自己的表。例如,我们有一个文档类型的继承层次结构,其中有两个类型:文本文档和图像文档。
public class Document
{
public int Id { get; set; }
public string Name { get; set; }
public string FileName { get; set; }
}
public class TextDocument : Document
{
public string Content { get; set; }
}
public class ImageDocument : Document
{
public byte[] ImageData { get; set; }
public string ImageType { get; set; }
}
在这个例子中,我们定义了一个 Document 类,它有一个 Id、Name 和 FileName 属性,用于标识文档。TextDocument 和 ImageDocument 继承自 Document 类,并添加了它们自己的属性。
为了实现 Table per Type 模式,我们需要使用多个表来表示每个实体类型。在本例中,我们需要创建一个 Documents 表,一个 TextDocuments 表和一个 ImageDocuments 表:
public class DocumentContext : DbContext
{
public DbSet<Document> Documents { get; set; }
public DbSet<TextDocument> TextDocuments { get; set; }
public DbSet<ImageDocument> ImageDocuments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Document>()
.ToTable("Documents")
.HasKey(d => d.Id);
modelBuilder.Entity<TextDocument>()
.ToTable("TextDocuments")
.HasKey(d => d.Id);
modelBuilder.Entity<ImageDocument>()
.ToTable("ImageDocuments")
.HasKey(d => d.Id);
base.OnModelCreating(modelBuilder);
}
}
在模型构建器中,我们通过调用 Entity 方法并使用 ToTable 方法来让每个实体类型使用自己的表。我们也设置了每个实体类型的主键。
现在,我们可以通过 DocumentContext 上下文对象查询和保存不同类型的文档。
继承是一种常见的程序设计模式,它在 Entity Framework 中也适用。在本文中,我们介绍了两种继承模式: Table per Hierarchy 和 Table per Type。 在这两种模式中,都有一些技术需要掌握,但它们可以简化模型,并且有助于保持代码的清晰。