且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

返回 IEnumerable<T>与 IQueryable<T>

更新时间:2022-05-06 15:51:02

是的,两者都会给你 延迟执行.

Yes, both will give you deferred execution.

区别在于 IQueryable<T> 是允许 LINQ-to-SQL(LINQ.-to-anything)工作的接口.因此,如果您在 IQueryable<T>,如果可能,该查询将在数据库中执行.

The difference is that IQueryable<T> is the interface that allows LINQ-to-SQL (LINQ.-to-anything really) to work. So if you further refine your query on an IQueryable<T>, that query will be executed in the database, if possible.

对于 IEnumerable<T> 情况下,它将是 LINQ-to-object,这意味着与原始查询匹配的所有对象都必须从数据库加载到内存中.

For the IEnumerable<T> case, it will be LINQ-to-object, meaning that all objects matching the original query will have to be loaded into memory from the database.

在代码中:

IQueryable<Customer> custs = ...;
// Later on...
var goldCustomers = custs.Where(c => c.IsGold);

该代码将执行 SQL 以仅选择黄金客户.另一方面,下面的代码会在数据库中执行原始查询,然后过滤掉内存中的非黄金客户:

That code will execute SQL to only select gold customers. The following code, on the other hand, will execute the original query in the database, then filtering out the non-gold customers in the memory:

IEnumerable<Customer> custs = ...;
// Later on...
var goldCustomers = custs.Where(c => c.IsGold);

这是一个非常重要的区别,正在处理 IQueryable<T> 在很多情况下可以避免从数据库返回太多行.另一个主要示例是进行分页:如果您使用 Take跳过IQueryable,你只会得到请求的行数;在 IEnumerable<T> 上执行此操作将导致您的所有行都加载到内存中.

This is quite an important difference, and working on IQueryable<T> can in many cases save you from returning too many rows from the database. Another prime example is doing paging: If you use Take and Skip on IQueryable, you will only get the number of rows requested; doing that on an IEnumerable<T> will cause all of your rows to be loaded in memory.