IQuerable与IEnumable的区别
核心区别:
IQueryable该接口会把查询表达式先缓存到表达式树Expression 中,只有当真正用到数据的时候(例如 遍历 ),才会由IQueryProvider解析表达式树,生成sql语句执行数据库查询操作。(离线集合)
IEnumable 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代。也就是说:实现了此接口的object,就可以直接使用foreach遍历此object;(本地集合)
(1)所有对于IEnumerable的过滤,排序等操作,都是在内存中发生的。也就是说数据已经从数据库中获取到了内存中,只是在内存中进行过滤和排序操作。
(2)所有对于IQueryable的过滤,排序等操作,只有在数据真正用到的时候才会到数据库中查询。这也是Linq的延迟加载核心所在。
案例一:
先上代码
- private void Form1_Load(object sender, EventArgs e)
- {
- using (DemoContext context = new DemoContext())
- {
- var customer = context.cunstomer.Where(c => c.Name == "牡丹");
- foreach (var item in customer)
- {
- MessageBox.Show(item.Id.ToString());
- }
- }
- }
至于代码中的上下文定义以及实体集大家不必纠结,我们在这里要透过表象看本质。在上面的程序中添加断点,同时启动sql server profiler监视工具,运行程序。
程序会在断点处停下来,如下所示
上面只是到点断点处,当然断点处的语句还有执行,继续单步执行。
执行过断点处所在的语句,观察监视工具还是什么都没有。
咦,是不是出什么问题了呢?为什么没有查询语句执行呢?真的是监视工具出问题了吗?
继续单步调试
咦,这个时候怎么出现sql查询语句了。很奇怪吧,这就是ado.net EF的延迟加载技术,这里面很重要的一部分就是通过IQueryable接口实现的(具体我们放到最后再说)。
讲过了Queryable类的Where方法,接下来我们再来看一下Enumable类的Where方法。
修改上面的代码如下所示
- private void Form1_Load(object sender, EventArgs e)
- {
- using (DemoContext context = new DemoContext())
- {
- var customer = context.cunstomer.Where(c => c.Name == "牡丹").AsEnumerable();
- foreach (var item in customer)
- {
- MessageBox.Show(item.Id.ToString());
- }
- }
- }
同样是打开监视工具,添加断点,运行程序
单步调试,继续运行
执行过断点所在的语句及执行了查询语句。
关于上面的两个测试总结如下。
(1)所有对于IEnumerable的过滤,排序等操作,都是在内存中发生的。也就是说数据已经从数据库中获取到了内存中,只是在内存中进行过滤和排序操作。
(2)所有对于IQueryable的过滤,排序等操作,只有在数据真正用到的时候才会到数据库中查询。这也是Linq的延迟加载核心所在。
案例二:
//linq 表达式的返回值的类型是IQueryable
IQueryable<HKSJ_USERS> temp = from u in dbContext.HKSJ_USERS
where u.ID >
select u;
//初始化了一下IQueryable接口里面的三个参数作用:
// 1 linq表达式转成表达式树Expression
// 2 给元素类型 Type ElementType赋值,这里指的是<HKSJ_USERS>
// 3 给提供者IQueryProvider Provider赋值,这里是efProvider,若是XML那就是xmlProvider,若是string 就stringProvider
所以理论上linq可以无限扩展。 //当用到 IQueryable接口的集合的数据的时候,provider解析Expression然后获取相应的数据。进行遍历执行。
//linq to ef:查询是在数据库端进行过滤。
foreach (var hksjUsers in temp)
{
Console.WriteLine(hksjUsers.ID + " " + hksjUsers.UserName);
} //IEnumable内存里面过滤:把数据库中的所有的数据都查询到程序里面来之后,再进行过滤。
//linq to object
var demoList = from u in dbContext.HKSJ_USERS.AsIEnumable() //ToList()
where u.ID >
select u;
foreach (var hksjUsers in demoList)
{ }
//List集合、Arrary,Dictionary,....都继承与IEnumable接口。
案例三
//查询的结果放入IQueryable接口的集合中
IQueryable<T_Class> classesIQue = (from c in schoolEntities.T_Class
orderby c.ID
select c).Skip<T_Class>(3).Take<T_Class>(3);
//注意这个AsEnumerable<T_Class>()在分页查询之前,先将其转换成IEnumerable类型
IEnumerable<T_Class> classesIEnu = (from c in schoolEntities.T_Class
orderby c.ID
select c).AsEnumerable<T_Class>().Skip<T_Class>(3).Take<T_Class>(3);
IQueryable接口(F12查看)
namespace System.Linq
{
public interface IQueryable : IEnumerable
{
Type ElementType { get; }
Expression Expression { get; }
IQueryProvider Provider { get; }
}
}
IEnumerable接口(F12查看)
namespace System.Collections
{
//
// 摘要:
// Exposes an enumerator, which supports a simple iteration over a non-generic collection.To
// browse the .NET Framework source code for this type, see the Reference Source.
[ComVisible(true)]
[Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerable
{
//
// 摘要:
// Returns an enumerator that iterates through a collection.
//
// 返回结果:
// An System.Collections.IEnumerator object that can be used to iterate through
// the collection.
[DispId(-)]
IEnumerator GetEnumerator();
}
}
namespace System.Collections
{
//
// 摘要:
// Supports a simple iteration over a non-generic collection.
[ComVisible(true)]
[Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
{
//
// 摘要:
// Gets the current element in the collection.
//
// 返回结果:
// The current element in the collection.
object Current { get; } //
// 摘要:
// Advances the enumerator to the next element of the collection.
//
// 返回结果:
// true if the enumerator was successfully advanced to the next element; false if
// the enumerator has passed the end of the collection.
//
// 异常:
// T:System.InvalidOperationException:
// The collection was modified after the enumerator was created.
bool MoveNext();
//
// 摘要:
// Sets the enumerator to its initial position, which is before the first element
// in the collection.
//
// 异常:
// T:System.InvalidOperationException:
// The collection was modified after the enumerator was created.
void Reset();
}
}
参考:
https://blog.csdn.net/ydm19891101/article/details/50969323
IQuerable与IEnumable的区别的更多相关文章
- IList,IQeurable,IEnumble和List 的区别
IList,IQeurable,IEnumble和List 的区别主要如下: 1.IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred exe ...
- IQueryable和IEnumerable,IList的区别
IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution) IQueryable和IEnumerabl ...
- C#中IEnumerable、ICollection、IList、IQueryable 、IQueryable 、List之间的区别
一:一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Reset ...
- 深入理解IEnumerable和IQueryable两接口的区别
from:http://blog.csdn.net/ydm19891101/article/details/50969323 无论是在ado.net EF或者是在其他的Linq使用中,我们经常会碰到两 ...
- IQueryable,IEnumerable,IList区别
IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution)IQueryable和IEnumerable ...
- c#与java的区别
经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...
- jquery和Js的区别和基础操作
jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...
- 【原】nodejs全局安装和本地安装的区别
来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ...
- 探究@property申明对象属性时copy与strong的区别
一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...
随机推荐
- 【MarkMark学习笔记学习笔记】javascript/js 学习笔记
1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...
- UnionFind问题总结
UnionFind就是acm中常用的并查集... 并查集常用操作 另外补充一下STL常用操作 相关问题: 547. Friend Circles 纯裸题噢... class Solution { pu ...
- handoop安装部署集群
hdfs 1.0版本 一个namenode (secordary namenode 2.0冷备份) 和多个datanode构成分布式文件系统 mapreduce 一个 jobtracker 协调 ta ...
- 轮播图js编写
//面向对象 function Left() { this.index = 0; this.lefthover = $('#left-content'); this.listenhover(); th ...
- 使用CefSharp在.Net程序中嵌入Chrome浏览器(一)——简介
有的时候,我们需要在程序中嵌入Web浏览器,其实.Net Framework中本身就提供了WebBrowser控件,本身这个是最简单易用的方案,但不知道是什么原因,这个控件在浏览网页的时候有些莫名的卡 ...
- Cordova - IOS浏览器里面数字被当做电话号码
网页上有连续超过5个数字,ios浏览器就会当做手机号码,如果某行文字有颜色,那么这个连续的数字就没颜色,变黑色了. 解决方法:在html页面头部加入下面代码 <meta name="f ...
- Android 经验之文件下载
在Android 开发中,我们肯定会接触到下载需求,那么如何通过技术实现呢? 一.简单实现: 通过了解HTTP原理,我们应该可以知道,HTTP学习的时候,可以通过HTTPGET方式来进行文件下载: n ...
- Java 字符串类型常用方法
常用方法 获取字符串长度 public int length() 字符串Unicode操作 这部分用的不多,不是很清楚,先记载在这. //获取指定索引处的元素对应的unciode编码 public i ...
- 教你怎么看网站是用react搭建的
概述 SPA和react可以说是web开发的分水岭,我一直在寻找判断网站是普通网站还是SPA抑或是react的方法.今天突然找到一个判断网站是不是react搭建的简便方法.现在记录下来供以后开发时参考 ...
- shell if 条件判断
condition='123' if [ -z condition]; then echo "condition 是空的" fi 字符串判断: = 两个字符串相等. != 两个字符 ...