我见过很多人都在谈论IQueryable
,我还没有完全了解所有的嗡嗡声。我总是使用泛型List
,并发现它们非常丰富,可以“查询”它们并使用它们,甚至对它们运行LINQ查询。
我想知道是否有充分的理由开始在我的项目中考虑不同的默认集合。
答案 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>
的查询语法的示例,请参阅我对此问题的回答: