在我的数据模型中,我有一个基类Case
,可以有几种不同的类型:Investigation
,DisciplinaryAction
等。这些都继承自{{1 }}。这就是我在实体框架中对其进行建模的方式。
Case
对于继承的类,public abstract class Case : BaseEntity
{
public int CaseId { get; set; }
public int PlanId { get; set; }
public int CaseTypeId { get; set; }
public CaseType CaseType { get; set; }
}
public class Investigation : Case
{
}
是主键和外键。我CaseId
只有一个DbSet
。当我需要显式访问其中一个继承类型时,我使用Cases
。这一切都很好。
在我的context.Cases.OfType<Investigation>()
中,我有一种通过ID获取案例的方法:
CaseRepository
我的问题是,对于其中一个继承类型,我想要包含另一个导航属性。有没有办法一般地访问继承的类型,并且包含并非所有继承类型都具有比这更不令人厌恶的方式的属性:
public Case GetById(int id)
{
var oversightCase = context.Cases
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.FirstOrDefault(f => f.CaseId == id);
}
答案 0 :(得分:1)
是的,当case id
与Investigation
相关时,您需要执行两项请求。像你写的那样做,不是正确的方法。
因为如果id
与Investigation
相关,那么您正在向数据库发出两个大请求,每个请求执行相同的前四个连接查询。
第二个请求(在if
语句块中)只是第一个请求的扩展,因为它们共享此代码:
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects)
为避免将来出现性能问题:
首先创建一个类似下面代码的泛型方法,其中T必须是Case
的子类:
public IQueryable<T> GetCaseCommonData<T>()
where T : Case
{
return context.Cases.OfType<T>
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects);
}
其次,使用如下通用方法:
public Case GetById(int id)
{
Case oversightCase;
if (context.Cases.OfType<Investigation>().Any(f => f.CaseId == id))
{
oversightCase = GetCaseCommonData<Investigation>()
.Include(p => p.Investigatee)
.SingleOrDefault(f => f.CaseId == id);
}
else
{
oversightCase = GetCaseCommonData<Case>()
.SingleOrDefault(f => f.CaseId == id);
}
return oversightCase;
}
使用我的解决方案,include
如下面的ocde执行一次:
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects);
通过像我一样重构代码,检查case id是否为Investigation
类型的查询比为同一目的编写的代码更有效:
context.Cases.OfType<Investigation>().Any(f => f.CaseId == id)