IQueryable 有什么大不了的?
我见过很多人在谈论 IQueryable
,但我还没有完全理解这些讨论的内容。我总是使用通用 List
,并发现它们的方式非常丰富,您可以“查询”它们并使用它们,甚至可以对它们运行 LINQ 查询。
我想知道是否有充分的理由开始在我的项目中考虑不同的默认集合。
I've seen a lot of people talking about IQueryable
and I haven't quite picked up on what all the buzz is about. I always work with generic List
's and find they are very rich in the way you can "query" them and work with them, even run LINQ queries against them.
I'm wondering if there is a good reason to start considering a different default collection in my projects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
IQueryable
接口允许您通过多个步骤并延迟执行来定义针对远程 LINQ 提供程序(通常针对数据库,但并非必须如此)的部分查询。例如,您的数据库层可以通过在查询中添加
.Where(x => x.......)
子句来定义一些限制(例如,基于权限、安全性等)。但这还没有被执行 - 例如,您没有检索与该条件匹配的 150'000 行。相反,您将 IQueryable 接口传递到下一个级别,即业务层,您可能会在其中向查询添加额外的要求和 where 子句 - 再说一遍,目前还没有执行任何操作,您还不会丢弃检索到的 150'000 行中的 80'000 行 - 您只是定义其他查询条件。
UI 层可能会做同样的事情,例如基于表单或其他内容中的用户输入。
神奇之处在于,您通过所有层传递 IQueryable 接口,为其添加额外的条件 - 但直到您实际强制执行它时,它才会被执行/评估。这也意味着您不会不必要地选择和检索随后最终丢弃的大量数据。
您实际上无法使用经典的静态列表来做到这一点 - 您必须选择数据,可能会在稍后的过程中再次丢弃大量数据 - 毕竟您有一个静态列表。
The
IQueryable
interface allows you to define parts of a query against a remote LINQ provider (typically against a database, but doesn't have to be) in multiple steps, and with deferred execution.E.g. your database layer could define some restriction (e.g. based on permissions, security - whatever) by adding a
.Where(x => x.......)
clause to your query. But this doesn't get executed just yet - e.g. you're not retrieving 150'000 rows that match that criteria.Instead, you pass up the
IQueryable
interface to the next level, the business layer, where you might be adding additional requirements and where clauses to your query - again, nothing gets executed just yet, you're also not tossing out 80'000 of your 150'000 rows you retrieved - you're just defining additional query criteria.And the UI layer might do the same thing, e.g. based on user input in a form or something.
The magic is that you're passing the
IQueryable
interface through all the layers, adding additional critieria to it - but it doesn't get executed / evaluated until you actually force it. This also means you're not needlessly selecting and retrieving tons of data which you end up discarding afterwards.You can't really do that with a classic static list - you have to pick the data, possibly discarding a lot of it again later on in the process - you have a static list, after all.
IQueryable 允许您使用 LINQ 进行查询,就像 LINQ to Object 查询一样,其中查询实际上是“编译”并在其他地方运行的。
最常见的实现是针对数据库的。如果您使用
List
和 LINQ to Objects,则会将整个数据“表”加载到内存中,然后对其运行查询。通过使用
IQueryable
,LINQ 提供程序可以将您的 LINQ 语句“翻译”为实际的 SQL 代码,并在数据库上运行。结果可以返回给您并进行枚举。这非常非常高效,特别是当您在 N 层系统中工作时。
IQueryable allows you to make queries using LINQ, just like the LINQ to Object queries, where the queries are actually "compiled" and run elsewhere.
The most common implementations work against databases. If you use
List<T>
and LINQ to Objects, you load the entire "table" of data into memory, then run your query against it.By using
IQueryable<T>
, the LINQ provide can "translate" your LINQ statement into actual SQL code, and run it on the database. The results can be returned to you and enumerated.This is much, much more efficient, especially if you're working in N-Tiered systems.
针对
IEnumerable
的 LINQ 查询会生成委托(方法),在调用该委托时,会执行所描述的查询。针对
IQueryable
的 LINQ 查询生成表达式树< /a>,表示生成查询的代码的数据结构。 LINQ to SQL 等 LINQ 提供程序解释这些数据结构,在目标平台(本例中为 T-SQL)上生成相同的查询。有关编译器如何根据
IQueryable
解释查询语法的示例,请参阅我对此问题的回答:基于组合框值构建动态 LINQ 查询
LINQ queries against
IEnumerable<T>
produce delegates (methods) which, when invoked, perform the described query.LINQ queries against
IQueryable<T>
produce expression trees, a data structure which represents the code that produced the query. LINQ providers such as LINQ to SQL interpret these data structures, generating the same query on the target platform (T-SQL in this case).For an example of how the compiler interprets the query syntax against
IQueryable<T>
, see my answer to this question:Building Dynamic LINQ Queries based on Combobox Value