IEnumerable<T> 和 IQueryable<T> 澄清?
Posted
技术标签:
【中文标题】IEnumerable<T> 和 IQueryable<T> 澄清?【英文标题】:IEnumerable<T> and IQueryable<T> clarification? 【发布时间】:2012-06-23 09:02:17 【问题描述】:看完this的问题, 我需要澄清一些事情。
IQueryable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;
IEnumerable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;
问题:
1) 可以这样说:在第一个查询中,SQLServer 正在运行整个操作,包括 where 子句并返回 ONLY 相关行 - 而第二个查询则执行 SELECT *
.. . 并将 所有 行返回到 C# 和 THEN 过滤器中?
2) 如果我只有一个 集合 - 在内存中怎么办。 (var lstMyPerson = new List<MyPerson>()
)
IQueryable<MyPerson> lst = from c in lstMyPerson
where c.City == "<City>"
select c;
对
IEnumerable<MyPerson> custs = from c in lstMyPerson
where c.City == "<City>"
select c;
现在执行会有什么不同?
【问题讨论】:
看看这个相关主题:***.com/questions/252785/…。而且,您在#1中的假设是正确的。不是 100% 确定 #2,所以我会把它留给另一个人。 @blizz 我已经读过了。所有答案都来自一本书 POV。那里没有回答我的问题.... :(...我会很高兴看看哪一行回答了我的问题 【参考方案1】:1:不,不正确
由于您只是将结果存储到IEnumerable<Customer>
,但仍然具有产生结果的完全相同的表达式,因此它们都将在服务器上执行并仅返回相关行。
你会得到不同的行为:
IEnumerable<Customer> custs = from c in (IEnumerable<Customer>)db.Customers
where c. City == "<City>"
select c;
在这种情况下,您将强制将 db.Customers
集合用作 IEnumerable<T>
,在枚举时将获取整个集合。
请注意:
IEnumerable<Customer> x = from c in db.Customers
where c.City == "<City>"
select c;
和这个不一样:
IEnumerable<Customer> x = from c in db.Customers
select c;
IEnumerable<Customer> y = x.Where(c => c.City == "<City>");
在第一种情况下,where
子句将成为 SQL 的一部分,而在第二种情况下则不会。这就是为什么链接的问题/答案涉及差异,而您的代码没有。
还请注意,只有您编写的语句实际上不会在服务器上执行任何操作,因为它们实际上只会存储惰性集合。如果您继续枚举这些集合,届时相关位将在服务器上执行。
2:List<T>
没有实现或具有IQueryable<T>
的扩展方法,所涉及的 LINQ 运算符也不会返回与 IQueryable<T>
兼容的任何内容
在这种情况下,第一个不会编译。
【讨论】:
不,正如我所说,他们都会这样做。但是,在链接代码的情况下,Where
LINQ 运算符应用于IEnumerable<T>
或IQueryable<T>
,您已将where
子句添加到原始查询。这会更改操作的顺序,因此在您的情况下,它们将以相同的方式执行。在链接的答案中,他们不会。
关于强制将 db.Customers 集合用作 IEnumerable3'rd
代码示例中:第一行实际上并没有从数据库中获取数据。播种为什么下一行不能只添加where
子句? (所以在枚举整个查询时将被发送到数据库)?这种行为是因为第一行使用Ienumerable
还是因为第二行使用Ienumerable
或者因为x.where
抱歉回复晚了。原因是编译器不再知道该集合是可以查询的。这意味着由于集合已存储到IEnumerable<Customer>
,IQueryable<T>
运算符不再可用。因此,答案中的最后一个分配将生成另一个惰性集合,但是这个集合在枚举完时会首先从数据库中获取每个客户,然后在内存中进行过滤。以上是关于IEnumerable<T> 和 IQueryable<T> 澄清?的主要内容,如果未能解决你的问题,请参考以下文章
将 IEnumerable<Ienumerable<T>> 转换为 Dictionary<key,IEnumerable<T>>
如何将两个 IEnumerable<T> 连接成一个新的 IEnumerable<T>?