实体框架 - 包含继承类型

时间:2016-02-21 03:43:24

标签: c# entity-framework inheritance

在我的数据模型中,我有一个基类Case,可以有几种不同的类型:InvestigationDisciplinaryAction等。这些都继承自{{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);
}

1 个答案:

答案 0 :(得分:1)

是的,当case idInvestigation相关时,您需要执行两项请求。像你写的那样做,不是正确的方法。 因为如果idInvestigation相关,那么您正在向数据库发出两个大请求,每个请求执行相同的前四个连接查询

第二个请求(在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)