核心区别:

IQueryable该接口会把查询表达式先缓存到表达式树Expression 中,只有当真正用到数据的时候(例如 遍历 ),才会由IQueryProvider解析表达式树,生成sql语句执行数据库查询操作。(离线集合)

IEnumable 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代。也就是说:实现了此接口的object,就可以直接使用foreach遍历此object;(本地集合)

(1)所有对于IEnumerable的过滤,排序等操作,都是在内存中发生的。也就是说数据已经从数据库中获取到了内存中,只是在内存中进行过滤和排序操作。

(2)所有对于IQueryable的过滤,排序等操作,只有在数据真正用到的时候才会到数据库中查询。这也是Linq的延迟加载核心所在。

案例一:

先上代码

  1. private void Form1_Load(object sender, EventArgs e)
  2. {
  3. using (DemoContext context = new DemoContext())
  4. {
  5. var customer = context.cunstomer.Where(c => c.Name == "牡丹");
  6. foreach (var item in customer)
  7. {
  8. MessageBox.Show(item.Id.ToString());
  9. }
  10. }
  11. }

至于代码中的上下文定义以及实体集大家不必纠结,我们在这里要透过表象看本质。在上面的程序中添加断点,同时启动sql server profiler监视工具,运行程序。

程序会在断点处停下来,如下所示

上面只是到点断点处,当然断点处的语句还有执行,继续单步执行。

执行过断点处所在的语句,观察监视工具还是什么都没有。

咦,是不是出什么问题了呢?为什么没有查询语句执行呢?真的是监视工具出问题了吗?

继续单步调试

咦,这个时候怎么出现sql查询语句了。很奇怪吧,这就是ado.net EF的延迟加载技术,这里面很重要的一部分就是通过IQueryable接口实现的(具体我们放到最后再说)。

讲过了Queryable类的Where方法,接下来我们再来看一下Enumable类的Where方法。

修改上面的代码如下所示

  1. private void Form1_Load(object sender, EventArgs e)
  2. {
  3. using (DemoContext context = new DemoContext())
  4. {
  5. var customer = context.cunstomer.Where(c => c.Name == "牡丹").AsEnumerable();
  6. foreach (var item in customer)
  7. {
  8. MessageBox.Show(item.Id.ToString());
  9. }
  10. }
  11. }

同样是打开监视工具,添加断点,运行程序

单步调试,继续运行

执行过断点所在的语句及执行了查询语句。

关于上面的两个测试总结如下。

(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的区别的更多相关文章

  1. IList,IQeurable,IEnumble和List 的区别

    IList,IQeurable,IEnumble和List 的区别主要如下: 1.IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred exe ...

  2. IQueryable和IEnumerable,IList的区别

    IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution) IQueryable和IEnumerabl ...

  3. C#中IEnumerable、ICollection、IList、IQueryable 、IQueryable 、List之间的区别

    一:一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Reset ...

  4. 深入理解IEnumerable和IQueryable两接口的区别

    from:http://blog.csdn.net/ydm19891101/article/details/50969323 无论是在ado.net EF或者是在其他的Linq使用中,我们经常会碰到两 ...

  5. IQueryable,IEnumerable,IList区别

    IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution)IQueryable和IEnumerable ...

  6. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

  7. jquery和Js的区别和基础操作

    jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...

  8. 【原】nodejs全局安装和本地安装的区别

    来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ...

  9. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

随机推荐

  1. 【MarkMark学习笔记学习笔记】javascript/js 学习笔记

    1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...

  2. UnionFind问题总结

    UnionFind就是acm中常用的并查集... 并查集常用操作 另外补充一下STL常用操作 相关问题: 547. Friend Circles 纯裸题噢... class Solution { pu ...

  3. handoop安装部署集群

    hdfs 1.0版本 一个namenode (secordary namenode 2.0冷备份) 和多个datanode构成分布式文件系统 mapreduce 一个 jobtracker 协调 ta ...

  4. 轮播图js编写

    //面向对象 function Left() { this.index = 0; this.lefthover = $('#left-content'); this.listenhover(); th ...

  5. 使用CefSharp在.Net程序中嵌入Chrome浏览器(一)——简介

    有的时候,我们需要在程序中嵌入Web浏览器,其实.Net Framework中本身就提供了WebBrowser控件,本身这个是最简单易用的方案,但不知道是什么原因,这个控件在浏览网页的时候有些莫名的卡 ...

  6. Cordova - IOS浏览器里面数字被当做电话号码

    网页上有连续超过5个数字,ios浏览器就会当做手机号码,如果某行文字有颜色,那么这个连续的数字就没颜色,变黑色了. 解决方法:在html页面头部加入下面代码 <meta name="f ...

  7. Android 经验之文件下载

    在Android 开发中,我们肯定会接触到下载需求,那么如何通过技术实现呢? 一.简单实现: 通过了解HTTP原理,我们应该可以知道,HTTP学习的时候,可以通过HTTPGET方式来进行文件下载: n ...

  8. Java 字符串类型常用方法

    常用方法 获取字符串长度 public int length() 字符串Unicode操作 这部分用的不多,不是很清楚,先记载在这. //获取指定索引处的元素对应的unciode编码 public i ...

  9. 教你怎么看网站是用react搭建的

    概述 SPA和react可以说是web开发的分水岭,我一直在寻找判断网站是普通网站还是SPA抑或是react的方法.今天突然找到一个判断网站是不是react搭建的简便方法.现在记录下来供以后开发时参考 ...

  10. shell if 条件判断

    condition='123' if [ -z condition]; then echo "condition 是空的" fi 字符串判断: = 两个字符串相等. != 两个字符 ...