实体框架核心忽略.include(..)而没有.ToList(..) [英] Entity Framework Core ignoring .Include(..) without .ToList(..) indirectly
问题描述
如EF核心文档加载相关数据中 我们可以使用 .Include(..)
从 DbSet
(或通用)中快速加载导航属性 IQueryable< T>
链接回EF上下文)。
As noted in "Loading Related Data" from EF Core Documentation we can use .Include(..)
to Eagerly Load navigation properties from the DbSet
(or generic IQueryable<T>
linking back to an EF context).
这意味着,鉴于以下模型:
This means that, given the following models:
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; }
}
..这样的代码应该起作用:
.. then code such as the following should work:
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()
:
I note that there is a caveat where .Include()
could be ignored should a query not return the type that is initially requested:
如果更改查询以使其不再返回查询开始的实体类型的实例,那么将忽略include运算符。 [snip]默认情况下,当忽略包含运算符时,EF Core将记录警告。
If you change the query so that it no longer returns instances of the entity type that the query began with, then the include operators are ignored. [snip] By default, EF Core will log a warning when include operators are ignored.
我不确定在上面对 .Any()$ c $的调用中如何c>是相关的。是的,查询未返回原始类型(当然,它返回的是
bool
),但同时也未记录警告,以表明它已被忽略。
I'm not sure how, in the above call to .Any()
that is relevant. Yes, the query is not returning the original type (it's returning a bool
of course) but at the same time, the Warning is also not logged to advise that it is being ignored.
我的问题是:
- 这是一个用例吗?期望工作?我应该在EF Core中引发一个错误吗?
- 如果没有预期, a 解决方法如下(调用
.ToList()
),但这显然会加载所有内容,以查找.Any()
上是否有任何内容,这很容易成为查询(并且会在EF6中是这样)。要使此.Any()
在服务器端工作,而又不需要ToList放入内存,有什么解决方法?
- Is this a usage case that is expected to work? Should I raise a bug in EF Core?
- If it's not expected, a workaround is as below (to call
.ToList()
) but that would obviously load everything, to find out if we have anything on a.Any()
which could easily be a query (and would be as such in EF6). What is a workaround to get this.Any()
to work on the server side thus not requiring the ToList to put it in memory?
解决方法:
context.TestEntityAs
.Include(m => m.TestEntityB)
.ToList()
.Any(m => m.BProperty == "Hello World");
完全可复制的示例: https://gist.github.com/rudiv/3aa3e1bb65b86ec78ec6f5620ee236ab
推荐答案
取决于数据,实现此目标的有效方法可能是加载单个记录:
Depending on the data, likely the efficient way to achieve that would be to load a single record:
context.TestEntityAs
.Include(m => m.TestEntityB)
.Where(m => m.BProperty == "Hello World")
.FirstOrDefault() != null;
这篇关于实体框架核心忽略.include(..)而没有.ToList(..)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!