过滤时 Include() 的顺序对性能有影响吗?

Does the order of Include()s when filtering have an impact on performance?

这工作正常,我假设它加载所有实体与所有 FooBar children,然后根据 Foo 过滤结果值:

var baz = "sillystring";
context.Entities
       .Include(e => e.Foo)
       .Include(e => e.Bar)
       .Where(e.Foo == baz)
       .Select(e.Bar)
       .ToList();

那么,如果是这样的话,这是一个有用的优化吗?首先进行过滤,然后 Bar children 只包含实体的子集?

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

事实是,在这种情况下它真的无关紧要,因为两个 Includes 都被忽略了。您可以删除它们,查询将产生完全相同的 SQL 和结果。

这是因为 Include 仅在应用于查询结果根实体(如果有)时才有效。这意味着它们在投影 (Select) 查询到匿名/DTO/ViewModel 等类型时被忽略。只考虑直接返回实体类型的查询,正如我之前所说,如果 Includes 从该实体类型开始。

很多人误解了 Include 的目的。使用导航属性进行过滤、排序、分组、选择等的查询的正确运行根本不需要它们。它们的全部目的是 Load Related Entities.

在您的示例中,唯一有效的包含是 Bar 的导航属性,它们必须插入 Select(e => e.Bar) 之后。它们的顺序并不重要,SelectInclude 之间的 LINQ 运算符也不重要,因为它们不会更改查询结果类型。