IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别
注意:本文背景为 Linq to sql 。文中ie
指代IEnumerable
,iq
指代IQueryable
。
IQueryable 和 IEnumerable 的区别
IQueryable
延时执行;扩展方法接受的是Expression(必须要能转成sql,否则报错)IEnumerable
延时执行;扩展方法接受的是Func(C#语法)
AsEnumerable() 和 ToList() 的区别
ToList()
立即执行,加载数据到内存中。AsEnumerable()
延时执行,真正使用时才加载数据。
对IQueryable对象使用AsEnumerable()后,仍然是延时执行,不过此时对象本质已经变了。
前面已经说了IEnumerable的扩展方法接受的是Func(C#语法)
,当ie对象(iq转变)真正使用时,会有2个步骤:
- 它会把iq对象(转变之前的)的扩展方法翻译成sql语句,查询出数据加载到内存中,变为ie对象;
- 此时再把ie对象(转变之后的)的扩展方法,使用C#求解,得到最终结果。
例如:
iq对象的Skip、Take方法,会被翻译成sql,在数据库里执行取出最终结果。
而ie对象的Skip、Take方法,则会取出全部数据到内存中,在内存中执行Skip、Take,会耗费大量资源。
误区
误区1:对 iq对象 和 ie对象 使用foreach时,对于循环的每项都要查询数据库。
错误!
foreach针对的是数据集整体对象(枚举器?)。当使用foreach时,不管是iq对象还是ie对象,它们都是查询数据库一次,然后开始循环,直至循环结束。不过,当后续再次使用iq对象或ie对象的具体数据时,它们仍然会再次查询数据库。
结论
假设我们把最终数据之前的数据称为中间数据,那么:
- 当中间数据只是作为条件筛选,需要的只是层层筛选之后的最终数据时,应该继续使用IQueryable,防止加载不必要的数据到内存中。
- 当存在中间数据,且中间数据被重复使用时,应该使用IQueryable.ToList()立即加载到内存里使用(都被重复使用了,应该叫做最终数据了吧..);
- 如果中间结果无用,且想对IQueryable对象使用Func(C#语法)的扩展方法,应该使用IQueryable.AsEnumerable()转成IEnumerable对象,进行后续操作。
参考
- LINQ查询中的IEnumerable<T>和IQueryable<T>
- LINQ使用细节之.AsEnumerable()和.ToList()的区别
- 建议29:区别LINQ查询中的IEnumerabl<T>和IQueryable<T> - 陆敏技《编写高质量代码改善C#程序的157个建议》
IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别的更多相关文章
- LINQ使用细节之.AsEnumerable()和.ToList()的区别
先看看下面的代码,用了 .AsEnumerable(): 1 var query = (from a in db.Table2 where a = SomeCondition3 select a.So ...
- Linq中 AsQueryable(), AsEnumerable()和ToList()的区别和用法
Linq中 AsQueryable(), AsEnumerable()和ToList()的区别和用法:在写LINQ语句的时候,往往会看到AsEnumerable() ,AsQueryable() 和T ...
- MVC+Spring.NET+NHibernate .NET SSH框架整合 C# 委托异步 和 async /await 两种实现的异步 如何消除点击按钮时周围出现的白线? Linq中 AsQueryable(), AsEnumerable()和ToList()的区别和用法
MVC+Spring.NET+NHibernate .NET SSH框架整合 在JAVA中,SSH框架可谓是无人不晓,就和.NET中的MVC框架一样普及.作为一个初学者,可以感受到.NET出了MV ...
- IQueryable和IEnumerable
使用EF你必须知道这两个的区别,可以帮助我们的提升性能. 表达树:Linq 表达 ①IQueryable和IEnumerable IQueryable 延时执行:扩展方法接受的是Expression( ...
- C# IQueryable和IEnumerable的区别
在使用EF查询数据的时候,我们常用的查询数据方式有linq to sql,linq to object, 查询返回的结果有两种类型:IQueryable.IEnumerable,两者内部的处理机制是完 ...
- C#编程之IList<T>、List<T>、ArrayList、IList, ICollection、IEnumerable、IEnumerator、IQueryable 和 IEnumerable的区别
额...今天看了半天Ilist<T>和List<T>的区别,然后惊奇的发现使用IList<T>还是List<T>对我的项目来说没有区别... 在C#中 ...
- IQueryable和IEnumerable,IList的区别
IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution) IQueryable和IEnumerabl ...
- IQueryable 和 IEnumerable
IQueryable 和 IEnumerable 其实,对于上面的即有过虑又有排序的条件查询Linq语句,EF是读取数据库中整个Books表中的数据到内存,还是根据Linq查询语句智能的生成SQL再执 ...
- C#中IQueryable和IEnumerable的区别
最近的一个面试中,被问到IQueryable 和 IEnumerable的区别, 我自己看了一些文章,总结如下: 1. 要明白一点,IQueryable接口是继承自IEnumerable的接口的. 2 ...
随机推荐
- linux dev设备
/dev目录的文件都是设备,我们可以像操作文件一样操作设备.但是究竟什么才是设备文件哪?作为程序员不能用代码敲出来的概念我们都是不喜欢的,所以本文用shell来操作体验什么才是/dev文件. 我们执行 ...
- logrotate 学习使用
logrotate Summary : Rotates, compresses, removes and mails system log files Description : The logrot ...
- 全文索引CONTAINS语法
Like直接在数据据中查找可以查到所有所需记录但是会扫描整个表会影响性能CONTAINS是基于全文索引进行查询,查询结果受系统全文索引分词的方法影响查询结果会不全.Select * FROM A Wh ...
- 阿里的iptables,保存一份
# Generated by iptables-save v1.4.7 on Fri Apr 14 16:37:31 2017 *filter :INPUT ACCEPT [0:0] :FORWARD ...
- bootstrap只有遮罩层没有对话框的解决方法
前端很差很差,猜测应该是各种js冲突的问题,换了一个jquery或bootstrap版本的不兼容. https://blog.csdn.net/Pabebe/article/details/70230 ...
- 51nod 1087 1 10 100 1000【打表】
题目来源: Ural 1209 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 1,10,100,1000...组成序列1101001000...,求 ...
- POJ 3620 Avoid The Lakes【DFS找联通块】
Avoid The Lakes Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6826 Accepted: 3637 D ...
- Python与数据库[2] -> 关系对象映射/ORM[0] -> ORM 与 sqlalchemy 模块
ORM 与 sqlalchemy 1 关于ORM / About ORM 1.1 ORM定义 / Definition of ORM ORM(Object Relational Mapping),即对 ...
- spoj 913 Query on a tree II (倍增lca)
Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...
- python 设计模式之中介模式
Mediator Pattern:中介模式 中介模式提供了一系列统一的系统接口.此模式也被认为是行为模式,因为他能选择程序处理流程. 当许多类开始在交互中产生结果时,可以选用中介模式.当软件开始组织 ...