【问题标题】:Convert an IQueryable linq query to IEnumerable<T> cancels out linq optimized way to work?将 IQueryable linq 查询转换为 IEnumerable<T> 会取消 linq 优化的工作方式吗?
【发布时间】:2013-02-12 21:29:04
【问题描述】:

我是 .NET 的新手,我想知道 linq 是如何工作的,因为您可以一个接一个地应用许多 linq 查询,但在它们用于传输信息或转换之前,它们都不会真正执行列出等。
有两种重要的方法可以获取 linq 查询,使用 IQueryable&lt;T&gt;,它直接在 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&lt;T&gt; 上获取,如果查询最终返回为 IEnumerable,那么查询是否真的在 sql 上过滤?还是在内存中?

【问题讨论】:

  • 对不起,如何查看日志?

标签: c# performance linq


【解决方案1】:

它仍然会在数据库中执行,不用担心。基本上,这完全取决于使用了Where 等的哪个实现。当你在IQueryable&lt;T&gt; 上调用方法时——通过Queryable 扩展方法——它将使用表达式树。当您开始从该查询中获取时,它将被转换为 SQL 并发送到数据库。

另一方面,如果您使用这些方法中的任何一个之后,您将其作为IEnumerable&lt;T&gt;(就编译时类型而言),它将使用扩展方法在Enumerable 中,所有其余的处理在进程中完成。

举个例子,考虑一下:

var query = db.People
              .Where(x => x.Name.StartsWith("J"))
              .AsEnumerable()
              .Where(x => x.Age > 20);

这里AsEnumerable() 只是返回它的输入序列,但输入为IEnumerable&lt;T&gt;。在这种情况下,数据库查询将只返回姓名以J 开头的人 - 然后将在客户端进行年龄过滤。

【讨论】:

  • 非常感谢您的回答!他们帮了很多忙!
【解决方案2】:

如果您返回 IEnumerable&lt;T&gt;,然后进一步细化查询,则进一步细化会在内存中进行。 IQueryable&lt;T&gt; 上表达的部分将被转换为适当的 SQL 语句(显然,对于 LINQ-to-SQL 的情况)。

请参阅Returning IEnumerable<T> vs. IQueryable<T> 以获得更长更详细的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-09
    • 2012-01-10
    • 2011-05-02
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 2010-09-07
    相关资源
    最近更新 更多