这很好用,我假设它将所有Foo
和Bar
子级都加载到所有实体中,然后根据Foo
的值过滤结果:
var baz = "sillystring";
context.Entities
.Include(e => e.Foo)
.Include(e => e.Bar)
.Where(e.Foo == baz)
.Select(e.Bar)
.ToList();
如果是这种情况,这是否是一个有用的优化方法,首先进行过滤,然后仅为实体的子集包括Bar
个子级?
var baz = "sillystring";
context.Entities
.Include(e => e.Foo)
.Where(e.Foo == baz)
.Include(e => e.Bar) // moved to after the filter
.Select(e.Bar)
.ToList();
...而且,EF是否足够聪明,以至于我在使用.Select(e.Bar)
时必须包含Bar
?
答案 0 :(得分:2)
事实是,在这种情况下,实际上并不重要,因为两个Includes
都会被忽略。您可以删除它们,查询将产生完全相同的SQL和结果。
这是因为Include
仅在应用于查询结果根实体(如果有)时才有效。这意味着对于匿名(DTO)/ ViewModel等类型的投影(Select
)查询,将忽略它们。仅考虑直接返回实体类型的查询,并且正如我之前所说,如果Include
从该实体类型开始。
许多人误解了Include
的目的。使用导航属性进行过滤,排序,分组,选择等的查询正常运行时,根本不需要它们。它们的全部目的都是为了Load Related Entities。
在您的示例中,唯一有效的包含将是Bar
的导航属性,并且必须在之后 Select(e => e.Bar)
处插入它们。它们的顺序无关紧要,以及Select
和Include
之间的LINQ运算符也很重要,因为它们不会更改查询结果类型。