繼承關系映射到數據庫表中有多種方式:
第一種:TPH(table-per-hiaerachy) 每一層次一張表 (只有一張表)
僅使用名為父類的類型名的一張表,它包含了各個子類的所有屬性信息,使用區分列(Disciriminator column)(通常內容為子類的類型名)來區分哪一行表示什么類型的數據。
第二種:TPT(Table-per-type) 每種類型都有一張表(父類及每個子類都有表)
父類、各子類各自都有一張表。父類的表中只有共同的數據,子類表中有子類特定的屬性。TPT很像類的繼承結構。父表格與子表格間通過外鍵關聯。
第三種:TPC(table-per-Concrete Class)具體子類一張表(子類有表)
映射非抽象類到各自的表。每個具體類的屬性,包括共有的繼承屬性,都會映射到各自的數據庫表中。它的數據庫的結構與沒有實現繼承關系的一樣。
TPC、TPH繼承模式一般有更好的性能,因為TPT會導致復雜的連接查詢。
這三種EF數據庫映射模式都可以使用Fluent API來實現,通過覆寫DbContext 類的中OnModelCreatin方法。
一、TPH的實現。
在Entity Framework 中,繼承關系默認使用TPH模式。
使用方法:
1、先定義父類。子類繼承父類,並實現自己的屬性。
2、將父類和子類加入到Context當中。如
public DbSet<Person> People {get;set;}
public DbSet<Instructor> Instructors {get;set;}
public DbSet<Student> Students {get;set;}
這樣,在數據庫中只會有Person 一張表了,並產生了一個Discriminator 列來區分行是表示 Student還是表示Instructor.
二、TPT的實現
例子:
modelBuilder.Entity<Person>().ToTable("Person");
modelBuilder.Entity<Student>().ToTable("Student");
modelBuilder.Entity<Instructor>().ToTable("Instructor");
三、TPC的實現
例子:
modelBuilder.Entity<Person>()
.Property(c => cID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Instructor>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Instructor");
});
modelBuilder.Entity<Student>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Student");
});