Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 实体框架6在相关实体已加载时执行导航属性访问查询_Entity Framework_Entity Framework 6 - Fatal编程技术网

Entity framework 实体框架6在相关实体已加载时执行导航属性访问查询

Entity framework 实体框架6在相关实体已加载时执行导航属性访问查询,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,我正在解决延迟加载问题(是的,我也会研究关闭它)。为简化起见,假设我有三个表,表A、表B和表C,它们处于一对多关系中:表A 1->*表B 1->*表C 出于各种原因,我避免在初始查询中包含TableC,因此我的第一步如下所示: var data = ctx.TableA.Include("TableB").Where(it => it.ID = 5); 因为我在TableB中拥有所有需要的实体,所以我正在收集它们的主键,并使用它们在TableC中大量加载相关实体 var ids = da

我正在解决延迟加载问题(是的,我也会研究关闭它)。为简化起见,假设我有三个表,表A、表B和表C,它们处于一对多关系中:表A 1->*表B 1->*表C

出于各种原因,我避免在初始查询中包含TableC,因此我的第一步如下所示:

var data = ctx.TableA.Include("TableB").Where(it => it.ID = 5);
因为我在TableB中拥有所有需要的实体,所以我正在收集它们的主键,并使用它们在TableC中大量加载相关实体

var ids = data.SelectMany(it => it.TableB.ID).ToList();
我尝试了以下两种方法:

var x1 = ctx.TableC.Where(it => ids.Contains(it.TableB_ID)).ToList();
var x2 = ctx.TableC.SqlQuery(String.Format("SELECT * FROM TableC WHERE TableB_ID in ({0})", String.Join(",", ids.Select(it => it.ToString())))).ToList();
通过调试,我可以看到执行的所有查询

我的问题是:当我执行以下代码时,EF执行一个查询来加载相关的TableC实体,而我的期望是不会执行SQL查询,因为请求的实体已经加载。

foreach (var tb in data.TableB)
{
    var res = tb.TableC;
    DoSomething(res);
}

我知道这里有些事情可能是不好的做法,我真的只是想了解关于这个特定设置的情况,而不是深入讨论编码实践,除非它直接涉及到这个问题。谢谢

你在这里干什么

var x1 = ctx.TableC.Where(it => ids.Contains(it.TableB_ID)).ToList();
(最好是

ctx.TableC.Where(it => ids.Contains(it.TableB_ID)).Load();
相同,但没有列表创建开销)

是一种变体,更一般地说,是一种所谓的导航属性修复

但是,尽管它填充了相应的集合,但它们没有标记为已加载,因此延迟加载仍将在首次访问属性时尝试加载它们。这是因为这种技术不能保证集合完全加载,例如用于加载过滤数据,如链接文档主题的“在显式加载相关实体时应用过滤器”部分所述。在提供的示例之后,您可能会注意到以下内容:

使用查询方法时,通常最好关闭导航属性的延迟加载。这是因为,否则整个集合可能会在执行过滤查询之前或之后由延迟加载机制自动加载

这也适用于你的情况

很快,当计划使用这种显式加载技术时,您最好关闭延迟加载,否则它将有效地使所有这些工作变得多余,实际上将对整个过程产生负面影响