将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上被过滤了吗?还是在记忆中?

将IQueryable linq查询转换为IEnumerable<;T>;取消了linq优化的工作方式

它仍将在数据库中执行,不用担心。基本上,这完全取决于使用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>以获得更长、更详细的答案。