我有一个代码优先的 DbContext,它使用不同 DBSet 中的基类和子类
例如。数据库集动物;DbSet 狗;数据库集猫;
其中 Dog 和 Cat 是动物的子类。当数据库由代码优先 EF 5.0 生成时,我只得到一个表(动物)——正如我所期望的(并且想要三个)——动物、猫和狗。有没有办法让它做到这一点(使用流利的api?)?
我有一个代码优先的 DbContext,它使用不同 DBSet 中的基类和子类
例如。数据库集动物;DbSet 狗;数据库集猫;
其中 Dog 和 Cat 是动物的子类。当数据库由代码优先 EF 5.0 生成时,我只得到一个表(动物)——正如我所期望的(并且想要三个)——动物、猫和狗。有没有办法让它做到这一点(使用流利的api?)?
是的,有一种方法可以通过 fluent API 实现,但映射取决于您期望的继承类型。目前,您有默认的 Table-per-Hierarchy 继承映射,其中所有实体都映射到同一个表,并默认调用一个附加列,Discriminator
以在每条记录中存储的类型之间有所不同。
假设您有以下实体:
public class Animal {
public int Id { get; set; }
public string Name { get; set; }
}
public class Dog : Animal {
public string Breed { get; set; }
}
现在,如果您使用 Table-per-Type 继承映射:
public class Context : DbContext {
public DbSet<Animal> Animals { get; set; }
public DbSet<Dog> Dogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Dog>().ToTable("Dogs");
}
}
您将获得两个表:Animals
with Id
and Name
columns 和Dogs
with Id
and Breed
column。表之间也将存在一对一的关系,因为每个Dog
实体在两个表中都有其记录。
如果您使用 Table-per-Class 继承映射:
public class Context : DbContext {
public DbSet<Animal> Animals { get; set; }
public DbSet<Dog> Dogs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Dog>().Map(m => {
m.MapInheritedProperties();
m.ToTable("Dogs");
});
}
}
您将再次获得两张桌子。Animals
将与第一种情况相同,但Dogs
将包含来自父类和子类的列:Id
, Name
, Breed
. 这些实体之间也不会有任何关系,因为 Dog 将在其自己的类中拥有所有数据。
TPC 继承可能看起来更好,但使用起来要困难得多。例如,EF 不使用标识,Id
因为 Id 在 TPC 继承中的所有表中必须是唯一的。TPC 继承的基础实体中的导航属性也会导致问题。