有关AsQueryable和AsEnumerable总结

271 阅读4分钟

一、AsQueryable(): 先说说什么是 IQueryable,AsQueryable将一个序列向下转换为一个IQueryable, 它生成了一个本地查询的IQueryable包装。 1,lazy load 特性 以下是一段最常见的代码: var products = db.Product.where(p => p.Type == "food").select(p => new { p.Id, p.Name, p.CreateTime}); 注意: Select() 的返回类型为 IQueryable,为 IQueryable, 语句执行后不会立刻查询数据库, 而是在迭代使用 products 时才会查数据库, 具有 lazy load 的特性, 按需查数据库可提高程序效率。

2,高程序效率. 迭代时上面的代码类似于下面的 sql 语句: select Id, Name, CreateTime from Product where Type = 'food' 对 products 再次使用数据库查询操作, 运行时会把结果合并为1条 sql 语句, 如下, var products = db.Product.where(p => p.Type == "food").select(p => new { p.Id, p.Name, p.CreateTime});

var orderedProducts = products.OrderBy(p => p.CreateTime); 迭代时生成的 sql 语句类似: select Id, Name, CreateTime from Product where Type = 'food' order by CreateTime IQueryable 有诸多限制, 只支持数据库查询语法, 无法支持 Linq to object 的操作, 是LINQ TO SQL。 结论:AsQueryable将一个序列向下转换为一个IQueryable, 它生成了一个本地查询的IQueryable包装。

二、AsEnumerable() 同样支持 lazy load,是延迟执行的,实际上什么都没有发生,当真正使用对象的时候(例如调用:First, Single, ToList....的时候)才执行。 但不要滥用。迭代时遇到 AsEnumerable() 会先进行 sql 查询, 但是, 千万不要为了方便而滥用 AsEnumerable(), 可能会严重消耗资源,能进行 Linq to object 操作。

eg:var products = db.Product.AsEnumerable().Select(p => new {p.Id, p.Name, p.CreateTime.Date});

对IQueryable对象使用AsEnumerable()后,仍然是延迟执行,不过此时对象本质已经变了。 上面的代码在查询时会把整个Product表的结果存放进内存, 然后进行 .Select 查询,严重消耗资源。 结论:AsEnumerable将一个序列向上转换为一个IEnumerable, 强制将Enumerable类下面的查询操作符绑定到后续的子查询当中。

AsEnumerable()延迟执行,不会立即执行。当你调用.AsEnumerable()的时候,实际上什么都没有发生。

注意: IQueryable实现了IEnumberable接口。但IEnumerable 换成IQueryable后速度提高很多。 IQueryable接口与IEnumberable接口的区别:

IEnumerable 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,而IQueryable 是将Skip ,take 这些方法表达式翻译成T-SQL语句之后再向SQL服务器发送命令,它并不是把所有数据都加载到内存里来才进行条件过滤。

三、ToList() 调用 ToList() 会立刻查询并保存结果, 而不会等到迭代时才查询,作用和 lazy load 是相反的。 在需要得到完整结果后, 再处理的场景, 需要使用 ToList()。

转载于:www.cnblogs.com/cqj98k/p/10…

blog.csdn.net/weixin_3056…

AsQueryable 只是创建一个查询获取列表所需的指令。您可以稍后对查询进行进一步的更改,例如添加新的 Where 子句,这些子句会一直发送到数据库级别。

List 返回一个包含内存中所有项目的实际列表。如果您向其中添加新的 Where cluse,您将无法获得数据库提供的快速过滤。相反,您获取列表中的所有信息,然后过滤掉应用程序中不需要的信息。

image.png

目的: 在使用Linq进行数据集操作时,Linq不能直接从数据集对象中查询,所以使用AsEnumerable和AsQueryable将数据类型泛型化,以支持Linq语句。

区别: AsEnumerable将一个序列向上转换为一个IEnumerable,把结果集放到缓存中,后续查询都是对缓存操作; AsQueryable将一个序列向下转换为一个IQueryable,把查询转为SQL包,直接通过拼接好的SQL查询数据库。

使用环境: 由于AsEnumerable将查询到的结构集合放到缓存中,后续的筛选操作的操作对象是缓存,所以比起AsQueryable将筛选体条件整合成SQL语句的一次性查询,要耗费更多的资源。 因此当我们需要一次性返回数据集的时候,例如PageList分页操作,AsQueryable更适合;而当我们需要获取同一数据集的多种筛选结果时,例如需要返回客户的多种信息,可以先把客户信息放到缓存中,然后针对客户的各种条件(性别、区域、资金、规模等)做多向筛选,这里显然AsEnumerable更合适。

原文链接:blog.csdn.net/weixin_4225…