在每个类型继承方案的表中加载 EF 导航属性
Posted
技术标签:
【中文标题】在每个类型继承方案的表中加载 EF 导航属性【英文标题】:Load EF navigation property in a Table per Type Inheritance scenario 【发布时间】:2014-05-14 16:30:07 【问题描述】:我有一个与this question 非常相似的场景,但我正在尝试做一些更复杂的事情。
回顾一下,我基本上有一个案例列表,每个案例都有不同的类型:
Case -> CaseA
Case -> CaseB
Case -> CaseC
每个派生的Case
类都有一个或多个我需要包含的导航属性:
Case -> CaseA -> Employee
Case -> CaseB -> List<Something>
Case -> CaseC -> List<SomethingElse>
现在,我当然可以做一个大量的switch
声明,但我正在寻找这样的聪明东西:
foreach(var myCase in ListOfCases)
context.LoadAll(myCase); // <- THIS!
context.Entry(myCase).LoadAllProperties() // <- OR THIS...
// etc. etc.
当然,这些方法不存在,所以我想知道是否有人遇到过类似的问题,以及有什么好的和聪明的方法来解决它。
谢谢!
【问题讨论】:
您如何一次查询所有这些不同的案例类型?如果您查询基本案例,则它无权访问子案例的成员。 嗨代理,这正是我要解决的问题... :/ 在基础中有一个方法被子项覆盖并使用一些子项字段... 我认为您必须按类型加载每个案例,例如在引用的问题中。 AKA,一个大开关,但在上下文类中的一个函数中。 【参考方案1】:最终解决方案非常简单:什么都不做! :)
基本上,如果对象层次结构设置正确并且导航属性(和集合)都具有virtual
修饰符以便可以启用LazyLoading
,EF 将自行深入对象层次结构以加载在第一个SELECT
期间没有加载:
public CasesDbContext()
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
然后例如这是方法:
var result = new List<CaseViewModel>();
var cases = _casesRepository.All;
foreach (var customCase in cases)
result.Add(new CaseViewModel()
Complete = customCase.IsComplete(), // <- at this point, the customCase is
// the derived implementation
// but the full hierarchy is missing
);
这是一个示例派生类:
public class CaseB : Case
public int ReferenceId get; set;
public virtual Reference Reference get; set; // <- "virtual" here is important!
protected override bool IsComplete()
return Reference.Name == "Tallmaris"; // <- at this point the EF
// will load the Reference.
另一个需要注意的是,在遍历一组实体时加载引用可能会产生类似There is already an open DataReader associated with this Command which must be closed first
的错误。解决方案是在迭代之前使用ToList()
,或者在连接字符串中启用MultipleActiveResultSets
(感谢@Ladislav for his answer here)。
【讨论】:
以上是关于在每个类型继承方案的表中加载 EF 导航属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在代码中首先在 TPT(每种类型的表)继承中启用级联删除?