这是LINQ(集成化查询)的继续及补充,在前面我已经介绍过,在LINQ中,一个重要的特性就是延迟加载,是指查询操作并不是在查询运算符定义的时候执行,而是在真正使用集合中的数据时才执行(如:在遍历集合时调用MoveNext方法时)。下面是一个简单的实例:

            var num = new List<int>();
num.Add();
IEnumerable<int> query = num.Select(n => n * );
num.Add();
foreach (int n in query)
Console.WriteLine(n);

结果输出10   20.在上面的例子中,在创建查询语句后又向集合中加入新元素,这个新元素最终也出现在查询结果中。这就是因为查询语句是在遇到foreach之后才真正执行的,再例如:

            Action a = () => Console.WriteLine("Foo");
//没有在控制台输出任何内容
a();
//延迟执行,输出Foo

绝大部分标准的LINQ查询运算符都具有延迟加载这种特性,但也有例外:

  • 那些返回单个元素或返回一个数值的运算符,如First或Count。
  • 转换运算符:ToArray,ToList,ToDictonnary,ToLookup。

以上这些运算符都会触发LINQ语句立即执行,因为它们的返回值类型不支持延迟加载。

延迟加载的工作原理

LINQ查询运算符之所以有延迟加载功能,是因为每个返回值不是一般的数组或集合,而是一个经过封装的序列,这种序列通常情况下并不直接储存数据元素,它封装并使用运行时传递给它的集合,元素也由其他集合来储存,它实际上只是维护自己与数据集合的一种依赖关系,当有查询请求时,再到它以来的序列中进行真正的查询。查询运算符实际上是封装一系列的转换函数,这种转换函数可以将与之关联的数据转换为各种形式的序列。如果输出集合不需要转换的话,那么就不用执行查询运算符封装的转换操作,这个时候查询运算符实际上就是一个委托,进行数据转发而已。

例如调用Where运算符的时候,在Where内部所做的操作非常简单,根据Lambda表达式中指定的查询条件,对输入集合重新进行了筛选,保留那些符合条件的元素指针引用,当外部遍历Where的返回值时,Where回到它所关联的集合中进行真正的查询,然后返回查询结果。

IEnumerable<int> lessThanTen = new int[] { , ,  }.Where(n => n < );

当执行lessThanTen操作时,实际上,就是使用where运算符对封装序列进行筛选。

当需要使用一些有特殊功能的运算符时,我们可以自定义实现。例如下面这个实例所示,实现一个自定义的Select运算符:

        public static IEnumerable<TResult> Select<TSource,TResult>(
this IEnumerable<TSource> source,Func<TSource,TResult> selector)
{
foreach (TSource element in source)
yield return selector(element);
}

上面这个方法实际上就是在循环中返回yield类型的元素。所以当调用Select和Where查询运算符时,内部操作就是创建一个序列,然后将查询得到的元素存入这个新的序列中。

其实,在LINQ中,延迟加载特性是很重要的,这种设计将查询的转换和查询的执行进行了解耦,这使得我们可以将查询分成多个步骤来创建,有利于查询表达式的书写,而且在执行的时候按照一个完整的结构去查询,减少了对集合的查询次数,这种特性对数据库查询尤其重要。

LINQ之延迟加载及其原理的更多相关文章

  1. Linq之延迟加载特性

    目录 写在前面 系列文章 延迟加载 总结 写在前面 上篇文章介绍了linq中常见的几个关键字,并列举了几个例子,算是对linq如何使用有了初步了解.上篇文章中也提到了,能够使用linq的场合有一个要求 ...

  2. Linq、延迟加载、直接加载

    1.集合常用扩展方法 Where.Max.Min.OrderBy. Select.//投影后的IEnumerable对象可以通过,AsQueryable转换数据类型 First.FirstOrDefa ...

  3. Linq的延迟加载问题

    什么是延迟加载:所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作.可以简单理解为,只有在使用的时候,才会发出sql语句进行查询,数据是分N次读取. 什么是立即加载:所谓立即加载既是所有的 ...

  4. 转载有个小孩跟我说LINQ(重点讲述Linq中GroupBy的原理及用法)

    转载原出处: http://www.cnblogs.com/AaronYang/archive/2013/04/02/2994635.html 小孩LINQ系列导航:(一)(二)(三)(四)(五)(六 ...

  5. linq之延迟加载和即时加载+标准查询运算符

    延迟加载 Linq查询的执行结果是IEnumerable<T>类型,而对IEnumerable<T>,在内部,C#通过yield关键字实现迭代器达到延迟加载的目的.从而使Lin ...

  6. 图片延时加载原理 和 使用jquery实现的一个图片延迟加载插件(含图片延迟加载原理)

    图片加载技术分为:图片预加载和图片延时加载. javascript图片预加载和延时加载的区别主要体现在图片传输到客户端的时机上,都是为了提升用户体验的,延时加载又叫懒加载.两种技术的本质:两者的行为是 ...

  7. Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?

    Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询.在 Myba ...

  8. 使用NHibernate(8)-- 延迟加载

    1,延迟加载. 延迟加载,即用到的时候再加载数据.这种机制是非常有情怀的,比如一篇中的用户实体有标签.问题等导航属性,如果只是用到用户名去查询整个实体,则把相关的标签和问题也都加载,性能会比较低.而有 ...

  9. (第一篇) 一步一步带你了解linq to Object

    要想学好linq to object 我们必须要先学习lambda 表达式,学习lambda 表达式呢我们必须了解匿名函数和匿名类及扩展方法,学习匿名函数,我们必须学会委托,这是本文的宗旨.下面开始第 ...

随机推荐

  1. Sequence Project Showplan Operator 序列映射运算符

    Sequence Project Showplan Operator 序列映射运算符 序列映射运算符会从一个已经排序的集合里通过不停添加集合里的列执行计算. 运算符根据一个或多个列的值把输入集合分为多 ...

  2. Windows Azure 服务总线和物联网

    机器到机器 (M2M) 计算正迅速成为一种技术,所有开发人员和架构师需要拥抱. 许多研究表明一个未来世界的数百亿美元的设备 (在地球上的每一个人的出现).MSDN杂志有2篇文章讨论Azure服务总线和 ...

  3. 在MySQL的InnoDB存储引擎中count(*)函数的优化

    写这篇文章之前已经看过了很多数据库方面的优化内容,大部分都是加索引.使用事务.要什么select什么等等.然而,只是停留在阅读的层面上,很少有实践,因为没有遇到真实的项目,一切都是纸上谈兵.实践是检验 ...

  4. MySQL 常用的UPDATE操作

    标签:UPDATE 概述 测试环境:mysql 5.6.21 步骤 创建测试表 CREATE TABLE `product` ( `proID` ) NOT NULL AUTO_INCREMENT C ...

  5. [nRF51822] 8、基础实验代码解析大全 · 实验11 - PPI

    前一篇分析了前十个基础实验的代码,从这里开始分析后十个~ 一.PPI原理: PPI(Programmable Peripheral Interconnect),中文翻译为可编程外设互连. 在nRF51 ...

  6. lua中清空目录和递归创建目录

    lua中的 lfs.mkdir lfs.rmdir只能针对单个目录,且lfs.rmdir不能清空文件夹 于是我想到了使用os.execute 递归创建目录如下os.execute("mkdi ...

  7. Node.js + Web Socket 打造即时聊天程序嗨聊

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...

  8. Python 学习文章收藏

    作者 标题 rollenholt Python修饰器的函数式编程 - Rollen Holt - 博客园 rollenholt python操作gmail - Rollen Holt - 博客园 ro ...

  9. 优化MySchool数据库设计之【巅峰对决】

    优化MySchool数据库设计 之独孤九剑 船舶停靠在港湾是很安全的,但这不是造船的目的 By:北大青鸟五道口原玉明老师 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识 ...

  10. Step by step Dynamics CRM 2011升级到Dynamics CRM 2013

    原创地址:http://www.cnblogs.com/jfzhu/p/4018153.html 转载请注明出处 (一)检查Customizations 从2011升级到2013有一些legacy f ...