C# 将 IQueryable linq 查询转换为 IEnumerable<T> 会取消 linq 优化的工作方式吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14842176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:12:19  来源:igfitidea点击:

Convert an IQueryable linq query to IEnumerable<T> cancels out linq optimized way to work?

c#performancelinq

提问by Arturo Suarez

I'm kinda newbie on .NET, and I was wondering how does linq works, since you can aply many linq queries, one after another, but none of them are really executed until they're used to transfer information or converted to list, etc.
There are 2 important ways to get a linq query, by using IQueryable<T>, which aplies the where filters directly on the Sql, and IEnumerable which get all the records and then it work with them on memory. However, let's take a look on this code:

我是 .NET 上的新手,我想知道 linq 是如何工作的,因为您可以一个接一个地应用许多 linq 查询,但是在它们用于传输信息或转换为列表之前,它们都不会真正执行,等。
有两种重要的方法来获取 linq 查询,通过 using 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 i'm using Linq dynamic library, the direct result from this query is being get on IQueryable<T>, if the query is finally being returned as IEnumerable, is the query being really filtered on the sql? or is it in memory?

Depsite 我正在使用 Linq 动态库,此查询的直接结果正在获取IQueryable<T>,如果查询最终返回为IEnumerable,查询是否真的在 sql 上过滤?还是在内存中?

采纳答案by Jon Skeet

It's still going to execute in the database, don't worry. Basically it's all down to which implementation of Whereetc is used. While you're calling methods on IQueryable<T>- via the Queryableextension methods - it will be using expression trees. When you start to fetchfrom that query, it will be turned into SQL and sent to the database.

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

On the other hand, if you use any of those methods afteryou've got it as an IEnumerable<T>(in terms of the compile-time type), that will use the extension methods in Enumerable, and all of the rest of the processing wouldbe done in-process.

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

As an example, consider this:

例如,请考虑以下内容:

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

Here AsEnumerable()justreturns its input sequence, but typed as IEnumerable<T>. In this case, the database query would return only people whose name began with J- and then the age filtering would be done at the client instead.

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

回答by driis

If you return an IEnumerable<T>and then further refine the query, then the further refinement happens in memory. The part that was expressed on an IQueryable<T>will get translated to the appropiate SQL statements (for the LINQ-to-SQL case, obviously).

如果您返回 anIEnumerable<T>然后进一步细化查询,则进一步细化发生在内存中。在 an 上表达的部分IQueryable<T>将被转换为适当的 SQL 语句(显然,对于 LINQ-to-SQL 的情况)。

See Returning IEnumerable<T> vs. IQueryable<T>for a longer and more detailed answer.

有关更长更详细的答案,请参阅返回 IEnumerable<T> 与 IQueryable<T>