23

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

4

2 回答 2

38

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

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

例如,考虑一下:

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

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

于 2013-02-12T21:32:10.727 回答
5

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

有关更长更详细的答案,请参阅Returning IEnumerable<T> vs. IQueryable<T> 。

于 2013-02-12T21:31:15.323 回答