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.自己在开 ...
随机推荐
- (22)Embrace the near win
https://www.ted.com/talks/sarah_lewis_embrace_the_near_win/transcript?referrer=playlist-talks_to_get ...
- Python开发——5.函数
一.函数的定义 def test(x) "The Function definitions" x += return x def:定义函数的关键字 test:函数名 ():定义形参 ...
- QT在Linux下的安装
QT是一个跨平台的C++开发库,设计思想是同样的,C++无需修改就可以在windows.linux.macOS等平台上使用,他使开发更专注于构建软件的核心价值,而不是维护API.作为面向对象的框架,它 ...
- commons-text 生成指定长度的随机字符串
package com.skylink.junge.demo; import java.util.HashSet; import java.util.Set; import org.apache.co ...
- Linux链接脚本学习--lds
一.概论 ld: GNU的链接器. 用来把一定量的目标文件跟档案文件链接在一起,并重新定位它们的数据,链接符号引用. 一般编译一个程序时,最后一步就是运行ld进行链接 每一个链接都被一个链接脚本所控制 ...
- python chr()和ord()的含义和使用方法
通过help 查看相关函数的帮助文档 >>>help (chr) chr(...) chr(i) -> character Return a string of one cha ...
- [Objective-C语言教程]快速枚举(35)
快速枚举是Objective-C的功能,用于枚举集合. 因此,要了解快速枚举,首先需要了解集合,这将在下一节中进行说明. 1. Objective-C集合 集合是基本结构.它用于保存和管理其他对象. ...
- SQL查询去掉重复数据
本文主要总结数据库去掉重复数据的方法 去掉重复数据的方法: 第一种:distinct 根据单个字段去重,能精确去重: 作用在多个字段时,只有当这几个字段的完全相同时,才能去重: 关键字distinct ...
- gitlab服务部署及使用
一.什么是gitlib Gitlab 是一个基于Git实现的在线代码仓库托管软件,你可以用Gitlab自己搭建一个类似于Github一样的系统平台,一般搭建gitlab私服就是用在公司的内部 Gitl ...
- css实现纯文字内容元素透明背景(兼容IE6)
HTML: <div class="title-wrapper"> <span class="title"> <span clas ...