将IQueryable linq查询转换为IEnumerable<;T>;取消了linq优化的工作方式
本文关键字:linq 取消 方式 工作 gt 优化 lt 查询 IQueryable 转换 IEnumerable | 更新日期: 2023-09-27 17:58:56
我是.NET的新手,我想知道linq是如何工作的,因为你可以一个接一个地使用许多linq查询,但在它们被用来传输信息或转换为列表等之前,它们都不会真正执行。
有两种重要的方法可以获得linq查询,一种是使用IQueryable<T>
,它直接在Sql上应用where过滤器,另一种是IEnumerable,它获取所有记录,然后在内存上使用它们。然而,让我们来看看这个代码:
//Linq dynamic library
IQueryable<Table> myResult = db.Categories
.Where(a => a.Name.Contains(StringName))
.OrderBy("Name")
.Skip(0)
.Take(10);
if (myResult != null)
{
return myResult.AsEnumerable();
}
else
{ return null; }
Depsite我使用的是Linq动态库,这个查询的直接结果是在IQueryable<T>
上得到的,如果查询最终被返回为IEnumerable
,那么这个查询真的在sql上被过滤了吗?还是在记忆中?
它仍将在数据库中执行,不用担心。基本上,这完全取决于使用Where
等的哪个实现。当您通过Queryable
扩展方法调用IQueryable<T>
上的方法时,它将使用表达式树。当您开始从该查询中提取时,它将被转换为SQL并发送到数据库。
另一方面,如果在之后使用中的任何一个方法,则将其作为IEnumerable<T>
(就编译时类型而言),这将使用Enumerable
中的扩展方法,并且的所有其余处理都将在进程中完成。
举个例子,考虑一下:
var query = db.People
.Where(x => x.Name.StartsWith("J"))
.AsEnumerable()
.Where(x => x.Age > 20);
这里AsEnumerable()
只是返回其输入序列,但类型为IEnumerable<T>
。在这种情况下,数据库查询将只返回姓名以J
开头的人,然后在客户端进行年龄筛选。
如果返回一个IEnumerable<T>
,然后进一步细化查询,那么进一步的细化将在内存中进行。在IQueryable<T>
上表达的部分将被转换为适当的SQL语句(显然,对于LINQ到SQL的情况)。
请参阅返回IEnumerable<T>相对于IQueryable<T>以获得更长、更详细的答案。