流畅的API EF继承和映射
本文关键字:继承 映射 EF API | 更新日期: 2023-09-27 18:06:11
我有一个系统,有几个具有一对多关系(亲子)的自引用实体。我想为所有这些实体使用公共基类:
public class SelfReferencing
{
public SelfReferencing Parent {get; set;}
public ICollection<SelfReferencing> Children {get; set;}
}
并从selfreference继承特定的实体。当尝试执行以下操作时,Fluent API映射要求引用属性为定义类型:
modelBuilder.Entity<ConcreteSelfReferencing>()
.HasMany(e => e.Children)
.WithOptional(e => e.Parent);
那么,你能帮我找到一种利用继承并映射实体的可能性吗?
THX
注意:下面的例子被称为每层次表(TPH) -即所有包含在一个表中。单击此链接查看每个类型的表(Table-Per-Type, TPT),其中每种类型都有不同的表。
当使用基类型和继承类型时,您必须告诉EF如何确定特定继承类型的关联。
取你的代码:
public abstract class SelfReferencing
{
public SelfReferencing Parent { get; set; }
public ICollection<SelfReferencing> Children { get; set; }
}
public class ConcreteSelfReferencing : SelfReferencing
{
}
EF现在必须计算出该子类是ConcreteSelfReferencing
还是任何其他类型的子类。这是由表本身上的标识符决定的,列不是映射的部分。
再举一个例子,类似于我过去用过的:
public abstract class Policy
{
public int Id { get; set; }
public string PolicyNumber { get; set; }
}
public class InsurancePolicy : Policy
{
}
public class CarPolicy : Policy
{
}
表的结构如下:
| Id | PolicyNumber | Type | ..... |
1 CAR0001 C
2 ISN0001 I
要使EF正确地得到它们,您需要:
public class MyContext : DbContext
{
public MyContext() : base()
{
}
public DbSet<Policy> Policies { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
var policyMap = modelBuilder.Entity<Policy>();
// Set up discriminators
policyMap.Map<InsurancePolicy>(p => o.Requires("Type").HasValue("I"))
.Map<CarPolicy>(p => o.Requires("Type").HasValue("C"));
// Notice that `Type` is only used for the discriminators, not an actual
// mapped property
policyMap.HasKey(x=>x.Id);
policyMap.Property(x=>x.PolicyNumber);
}
}
在代码中,您可以自己进行过滤,也可以将过滤放在DbContext
中。下面是一个单独类的例子。
public class PolicyRepository
{
private MyContext context = new MyContext();
public PolicyRepository()
{
}
public IQueryable<InsurancePolicy> GetInsurancePolicies()
{
return this.context.Policies.OfType<InsurancePolicy>();
}
public IQueryable<CarPolicy> GetCarPolicies()
{
return this.context.Policies.OfType<CarPolicy>();
}
}