IQueryable有什么大不了的?

时间:2010-04-20 20:31:06

标签: linq architecture collections

我见过很多人都在谈论IQueryable,我还没有完全了解所有的嗡嗡声。我总是使用泛型List,并发现它们非常丰富,可以“查询”它们并使用它们,甚至对它们运行LINQ查询。

我想知道是否有充分的理由开始在我的项目中考虑不同的默认集合。

3 个答案:

答案 0 :(得分:44)

IQueryable接口允许您在多个步骤中使用延迟执行来针对远程LINQ提供程序(通常针对数据库,但不一定是)定义查询的各个部分。

E.g。您的数据库层可以通过向查询添加.Where(x => x.......)子句来定义一些限制(例如,基于权限,安全性等)。但是这还没有被执行 - 例如你检索符合该标准的150'000行。

相反,您将IQueryable接口传递到下一个级别,即业务层,您可能会在其中添加其他要求以及查询的子句 - 再次,还没有执行任何操作,您也是不要丢弃你检索到的150'000行中的80'000 - 你只是定义了额外的查询标准。

UI层可能会做同样的事情,例如基于表单中的用户输入。

神奇的是你通过所有层传递IQueryable接口,为它增加了额外的标准 - 但是在你真正强迫它之前它不会被执行/评估。这也意味着你不必不必要地选择和检索最后丢弃的大量数据。

你不能用经典的静态列表真正做到这一点 - 你必须选择数据,可能在以后的过程中再次丢弃很多数据 - 毕竟你有一个静态列表。

答案 1 :(得分:8)

IQueryable允许您使用LINQ进行查询,就像LINQ to Object查询一样,查询实际上是“编译”并在其他地方运行。

最常见的实现适用于数据库。如果使用List<T>和LINQ to Objects,则将整个“数据表”加载到内存中,然后针对它运行查询。

通过使用IQueryable<T>,LINQ提供可以将LINQ语句“转换”为实际的SQL代码,并在数据库上运行它。结果可以返回给您并枚举。

这是非常有效的,特别是如果你在N-Tiered系统中工作。

答案 2 :(得分:4)

针对IEnumerable<T>的LINQ查询生成委托(方法),在调用时,它们执行所描述的查询。

针对IQueryable<T>的LINQ查询生成expression trees,这是一种表示生成查询的代码的数据结构。诸如LINQ to SQL之类的LINQ提供程序解释这些数据结构,在目标平台上生成相同的查询(在本例中为T-SQL)。

有关编译器如何解释IQueryable<T>的查询语法的示例,请参阅我对此问题的回答:

Building Dynamic LINQ Queries based on Combobox Value