1. 首页
  2. 文章列表
  3. 浅谈EF中LINQ查询原理

在接触Linq之前,一直听说Linq被微软抛弃。后来才发现被抛弃的是Linq to SQL这种专用于操作Sql Server的轻型ORM,微软宣布停止更新Linq to Sql,把开发的重点从 Linq to SQL 转移到了 Linq to Entities。

在EF中使用Linq查询数据的基本形式是这样的:

var result = from t in Table where t.id > 10 select t;

这个形式在Linq to 各种都是通用的,下面讲一下它的原理。

很多人都以为,上面的语句执行过后就完成了查询操作,把查询的结果载入了result中,然而事实是上面的语句只完成了一个result对象的创建和初始化。事实上真正的查询是在foreach语句开始时发生的,查询到的数据载入,然后再遍历取数据。你可以尝试在Sql Server的profile工具中监控一下,上面的语句执行完成,数据库并没有监控到任何信息,当你尝试在"result“中拿数据的时候,profile工具监测到了数据库访问,这也就是延时加载,如果你想关闭延时加载可以在EF模型的属性中设置。

这里的result的类型其实是DbQuery,它有实现一个接口IQueryable<>,IQueryable<>是Linq命名空间下的一个特有的集合,它的类型参数是实体类或其父类,或者不用泛型,默认的是Object,这涉及到协变。由于采用了延时加载,所以说这是一种离线集合。也就是说你尝试在"result"中取一次数据,它就会去数据库查询一次,所以如果需要持续使用某些数据,应该是手动创建对象,存入本地内存中。

那么Linq查询的原理和IQueryable<>有什么关系呢?其实在IQueryable<>中仅有三个属性:

Type ElementType

Expression Expression

IQueryProvider Provider

我们在写Linq表达式并完成IQueryable<>对象创建的时候,它的初始化过程是这样的:声明元素类型,这一点从属性名字就可以看出来,然后建立Expression对象,这里就是把你写的Linq表达式进行解析,拆分,解析成一个表达式树,也就是对Lambda表达式的解析过程,Expression对象以二叉树结构存储解析结果。最后根据LINQ表达式类型给IQueryableProvider provider属性赋值。在你需要读取数据的时候Provider属性就去解析Expression表达式树执行查询返回。所以这就做到了不管你是Linq to Sql还是Linq to Entities,都能使用。

其实EF跨数据库的核心也在这里,目前多个数据库厂商开始逐渐支持EF,他们只需要做一个工作,那就是写对应数据库的Provider驱动即可,你可以在自己的项目中引用不同数据库的Provider,然后更改连接字符串的providerName属性就完成了跨数据库操作。

有时候我们可以直接把Linq的查询结果载入本地集合,也就是List,Array这样,存入内存中。Linq表达式可以这样写:

var result = from t in Table.ToList() where t.id > 10 select t;

这时候查询就变成了Linq to Object,上面不同,在这条语句执行完成过后,数据就已经从数据库中查询,载入内存,变成了Object。所以这里的所有操作都是在内存中进行,如果不适用ToList()函数,最后执行的SQL语句中加入了Linq表达式中的where条件,而这种方法则是将数据全部载入内存,在内存中使用where的筛选条件过滤。

下载为Word文档

版权声明:

本文仅用于学习、研究和交流目的,欢迎非商业性质转载。本文链接:https://masuit.com/99

l  博主在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系。挖井挑水无水表,不会网购无快递。

l  文章内容部分来源于互联网,不代表本人的任何立场;涉及到的软件来源于互联网,仅供个人下载使用,请勿用于商业用途,版权归软件开发者所有,下载后请于24小时内删除,请支持正版!因下载本站任何资源造成的损失,全部责任由使用者本人承担!如果你是版权方,认为本文内容对您的权益有所侵犯,请联系博主,待博主进行严格地审查和背景调查后,情况属实的将在三天内将本文删除或修正。

l  博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。

l  博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章,请原谅博主成为一个无耻的文档搬运工!

l  博主只是一名普通的互联网从业者,不懂修电脑,不会卖电脑,不会帮你盗号,不会破解开机密码,找不回你丢失的手机等,如有这样的想法请绕道!

相关推荐:

深入浅出依赖注入容器——Autofac .NET/java Office组件神器——Aspose.Total 17.x/18.x破解版+破解补丁下载
AutoMapper6.x起步 谈一谈.NET中的并行编程(TPL)——多线程、异步、任务和并行计算
五分钟重温C#委托,匿名方法,Lambda,泛型委托,表达式树 浅谈MVC的Attribute路由,教你一步一步设计出漂亮的路由
C# vs Java:C# 五个不可替代的特性瞬间秒杀 Java 经典面试题之——如何自由转换两个没有继承关系的字段及类型相同的实体模型
谈一谈单例模式、静态类和线程内唯一对象有什么区别 深入理解C#中的IDisposable接口

评论区:

    还没有评论哦,赶紧来写评论吧

    分享按钮