entity framework核心忽略.Include(..)而没有.ToList(..)间接

如EF Core Documentation中的“加载相关数据”中所述,我们可以使用.Include(..)来急剧地从DbSet加载导航属性(或通用IQueryable链接回EF上下文)。

这意味着,给定以下模型:

 public class TestEntityA { public int Id { get; set; } public int TestEntityBId { get; set; } public TestEntityB TestEntityB { get; set; } public string BProperty { get { return TestEntityB.Property; } } } public class TestEntityB { public int Id { get; set; } public string Property { get; set; } } 

..然后以下代码应该工作:

 context.TestEntityAs .Include(m => m.TestEntityB) .Any(m => m.BProperty == "Hello World"); /* * Note that the below DOES work by using the nav property directly * in the query, but that is not always going to be an option for * whatever reason. If it's .Included it should be available through * INNER JOINing it into the base query before the .Any runs. * .Any(m => m.TestEntityB.Property == "Hello World"); */ 

但事实并非如此。

我注意到有一个警告,如果查询没有返回最初请求的类型,则可以忽略.Include()

如果更改查询以使其不再返回查询开头的实体类型的实例,则忽略包含运算符。 [snip]默认情况下,EF Core会在忽略include运算符时记录警告。

我不确定如何在上面调用相关的.Any() 。 是的,查询没有返回原始类型(当然它返回bool )但同时,也没有记录警告以告知它被忽略。

我的问题是:

  • 这是一个预计会起作用的用例吗? 我应该在EF Core中提出错误吗?
  • 如果没有预料到,解决方法如下(调用.ToList() ),但显然会加载所有内容,以确定我们是否有任何关于.Any()内容可以很容易地成为查询(并且会如此在EF6)。 什么是解决方法来获得这个.Any()在服务器端工作,因此不需要ToList将其放入内存?

解决方法:

 context.TestEntityAs .Include(m => m.TestEntityB) .ToList() .Any(m => m.BProperty == "Hello World"); 

完全可重复的样本: https : //gist.github.com/rudiv/3aa3e1bb65b86ec78ec6f5620ee236ab

行为是预期的,但您可以使用显式加载来进行更有效的查询,如下所示。

2个单独的查询,但不需要加载所有TestEntityB

 // First query var testEntityAs = context.TestEntityAs.ToList(); var testEntityAsIds = testEntityAs.Select(t => t.Id); // Second query, can apply filter of Hello World without loading all TestEntityBs context.TestEntityBs .Where(t => testEntityAsIds.Contains(t.Id) && t.Property == "Hello World") .Load(); // In memory check var isAny = testEntityAs.Any(t => !string.IsNullOrEmpty(t.BProperty));