我无法用实体框架

时间:2016-10-13 14:49:38

标签: c# entity-framework

我试图找到有关Entity Framework中行为的文档。它有效但在依赖这种行为之前,我想确定它是EF的正常行为,而不是一个意想不到的副作用,它将被修复"在未来的版本中。情况如下:

我有一个非常深的对象层次(我将在这里简化)。该结构是一个多层次的对象集合(类A包含一个B类集合,其中包含一个C类集合,其中包含...),深度为7层。

我已经过滤了C的某些属性上的元素,我第一次尝试加载完整的层次结构会产生一个复杂的LINQ查询(这将是一个维护噩梦),并且生成的SQL查询远没有效率。为了简化这一切,我决定分两步拆分查询:首先,我按需要加载C类(及其所有子项)的集合,然后,我为包含B的所有B实例加载A和B类我过滤的C集合的项目。

这里有一个问题:使用这种技术,我预计必须在我的B类中手动重新填充C的集合,但实际上,该集合已经填充了集合的元素。我在intellitrace中验证了SQL查询,并且填充C实例所需的数据未包含在第二个查询中,因此唯一合乎逻辑的结论是EF通过上下文中的信息执行此操作。顺便说一句,在这种情况下,延迟加载是关闭的。

这种行为在EF中是否正常?这样,你能给我链接到解释其工作原理的文档吗?

这里有一个片段来说明这一点:

using(var context = new MyContext())
{
    //Includes and where clauses are greatly simplified for the purpose of the sample
    var filteredC = context.C.Include(x=>x.ListOfD).Include(x=>x.ListOfD.Select(y=>y.ListOfE)).Where(c=>c.Status==Status).ToList();

    int[] bToLoad = filteredC.Select(c=>c.IDofB).Distinct().ToArray();

    var listOfAAndB = context.A.Include(a=>a.ListOfB).Where(x=>x.ListOfB.Any(y=>bToLoad.Contains(y.ID))).ToList();

    //At this step, I expected B.ListOfC to be empty but it's somehow populated
}

由于

1 个答案:

答案 0 :(得分:3)

这是DbContext生命周期的标准行为。说实话,我无法将您链接到任何记录此功能的文档,但我可以向您解释这是如何工作的。

EF上下文是有状态的,并跟踪已经获取的所有实体。它还了解数据库中的实体与实体模型之间的关系。

因此,如果您获取与该对象具有直接关系的新对象(在您的情况下,C具有B的外键),则导航属性由Context填充。这是一个功能,而不是一个错误,因为它试图明确地避免对已经获取的对象的数据库加密查询。