IQueryable 和 IEnumerable 的区别
讲一讲 IQueryable 和 IEnumerable 的区别。
我们会在使用 LINQ 查询方法之后,又使用 ToList
等方法,将查询结果转换成集合。
如果我们不使用 ToList
呢?
比如这个示例:
using var context = new BloggingContext();
var posts = context.Posts.OrderBy(p => p.BlogId == 1).ToList();
var posts1 = context.Posts.OrderBy(p => p.BlogId == 1);
这里有两个查询,一个使用了 ToList
方法,另一个没有。
执行这段代码,在控制台中查看日志:
可以看到只有一条 SQL 语句被执行,按理说我们有两个 LINQ 查询,应该有两条 SQL 语句,但是只有一条,这是为什么?
其实,我们调用的 LINQ 查询方法,本身是不会执行查询操作的。
简单来说,我们执行的 LINQ 方法,只是转换成了查询表达式,被存储在了 IQueryable
类型的对象中。
只有当我们需要数据的时候,比如当我们使用 ToList
方法时,EF Core 才会将整个出啊讯表达式,翻译成 SQL 语句执行。
这种需要数据时才会查询的行为,看起来有点像显式加载,但绝对不是一回事儿。
结合示例简单的说,「post1」 只是一个以 LINQ 表达式体现的查询语句,就好比你编写了一条字符串 SQL 语句。
至于这条语句是否执行,取决于下一步操作。比如 ToList
方法,就是这一步查询操作。
因为使用 ToList
方法的目的,就是为了获取数据集合,所以 EF Core 才会执行这条查询语句。
如果非要给这种行为起一个名字的话,我觉得应该叫延迟执行更合适。
我们再来看看,LINQ 方法返回的数据类型是什么:
「post1」 的数据类型是泛型的 IOrderedQueryable
,它本质上是就是一个 IQueryable
类型,不过是具有排序表达式的 IQueryable
。
LINQ 方法往往都有好几个重载,比如 OrdeyBy
、Where
等方法,它们返回的数据类型有两种:IQueryable
和 IEnumerable
。
那么这两种数据类型究竟有何区别?我们做个试验:
在这个示例中,「posts」 和 「posts1」 的语句,可以视为等效的。
这是因为查询参数会被默认为 IQueryable
类型,所以最终使用的还是返回 IQueryable
类型的重载方法。
在 post2 的语句中,由于 IQueryable
继承了 IEnumerable
,所以可以通过 AsEnumerable
方法,将其返回值转换为 IEnumerable
类型。
在这种情况下,只有当代码运行到两个 foreach
遍历的时候,才会真正的执行语句。
接下来,再看这个示例:
这个示例与前面一个示例的不同之处在于,「posts1」 查询语句的 LINQ 方法在 AsEnumerable
之后才调用。
运行程序,观察控制台日志:
此时我们终于发现了不同,两条 SQL 语句不同,第一条 SQL 语句比第二条 SQL 语句多了一个分页操作。
IQueryable
在查询的时候,会应用所有 LINQ 方法,并且生成一个完整的 SQL 查询语句,去数据库执行并获取符合查询语句的数据;
而当我们使用 IEnumerable
时,则会生成一条将所有的数据查询出来的 SQL 语句,而后在内存中再对数据进行处理,最终获得符合查询语句的数据。
在不使用 AsEnumerable
的情况下,默认都是采用 IQueryable
进行查询。
那么我们什么时候应该使用 AsEnumerable
?
使用 「AsEnumerable」 的查询,称为客户端查询。
比如,当你想在客户端完成筛选或者聚合等操作的时候,可以选择转换成 IEnumerable
进行查询。
虽然这增大了数据库查询压力和IO压力,但因为将计算转移到了客户端,所以也相应的减轻了数据库的计算压力。
简单来说是,这是一种用 I/O 资源换计算资源的行为。
IQueryable 和 IEnumerable 的区别的更多相关文章
- C#编程之IList<T>、List<T>、ArrayList、IList, ICollection、IEnumerable、IEnumerator、IQueryable 和 IEnumerable的区别
额...今天看了半天Ilist<T>和List<T>的区别,然后惊奇的发现使用IList<T>还是List<T>对我的项目来说没有区别... 在C#中 ...
- C#中IQueryable和IEnumerable的区别
最近的一个面试中,被问到IQueryable 和 IEnumerable的区别, 我自己看了一些文章,总结如下: 1. 要明白一点,IQueryable接口是继承自IEnumerable的接口的. 2 ...
- C# IQueryable和IEnumerable的区别
在使用EF查询数据的时候,我们常用的查询数据方式有linq to sql,linq to object, 查询返回的结果有两种类型:IQueryable.IEnumerable,两者内部的处理机制是完 ...
- IQueryable与IEnumerable使用区别
IQueryable会将查询语法转化为SQL查询语句,去数据库查询:IEnumerable则查询整张表,加载到内存中,再进行筛选. 所以,当查询的数据量较大的时候,则使用IQueryable.反之,数 ...
- IQueryable和IEnumerable的区别
- IQueryable和IEnumerable,IList的区别
IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution) IQueryable和IEnumerabl ...
- IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别
注意:本文背景为 Linq to sql .文中ie指代IEnumerable,iq指代IQueryable. IQueryable 和 IEnumerable 的区别 IQueryable 延时执行 ...
- IQueryable,IEnumerable,IList区别
IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution)IQueryable和IEnumerable ...
- EF入门 IQueryable和IEnumberable的区别
IEnumerable接口 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代.也就是说:实现了此接口的object,就可以直接使用foreach遍历此object: IQueryable 接口 ...
- IQueryable和IEnumerable
使用EF你必须知道这两个的区别,可以帮助我们的提升性能. 表达树:Linq 表达 ①IQueryable和IEnumerable IQueryable 延时执行:扩展方法接受的是Expression( ...
随机推荐
- U盘插上电脑上后自动备份文件
缘由 一直有个不好的习惯,将所有文件都存在个人U盘,下班直接拔了就回家. 前久把U盘插入MacBook后,U盘就无法读数据了,搞了很久也没搞定. 当然了,里面的数据也无法使用了. 所以,现在的想法: ...
- 为win10添加右键“以管理员身份运行MSI”选项
win+r运行regedit以打开注册表编辑器 定位到HKEY_CLASSES_ROOT\Msi.Package\shell 右键shell,新建 项 项名称为runas 双击runas右边的默认,填 ...
- 第二性 合卷本 横本.EPUB
书本详情 第二性台版 作者: 西蒙.德.波娃(Simone de Beauvoir)出版社: 貓頭鷹原作名: Le Deuxième Sexe译者: 邱瑞鑾出版年: 2013-10页数: 1136装帧 ...
- 解决Google翻译不能用的问题
解决Google翻译不能用的问题 1.打开C:\Windows\System32\drivers\etc\hosts 2.在hosts后面加入 203.208.40.66 translate.go ...
- P5736 质数筛
原题连接 一看到这个熟悉的输入,我们就立马反应过来要请出一维数组来记录一下输入的数据.现在数据的存储解决了,紧接着来剖析一下步骤: 输入数据 一个一个的判断是否为质数 筛去合数 输出质数 理清了思路后 ...
- 并发多线程学习(六)Java线程间的通信
合理的使用Java多线程可以更好地利用服务器资源.一般来讲,线程内部有自己私有的线程上下文,互不干扰.但是当我们需要多个线程之间相互协作的时候,就需要我们掌握Java线程的通信方式.本文将介绍Java ...
- Rust智能指针
Rust智能指针 https://course.rs/advance/smart-pointer/intro.html Box 堆对象分配 Box指针拥有内存对象的独占使用权 (一)使用场景 1. 使 ...
- pyton3 字典排序
1. 字典排序 d={'a':1,'c':3,'b':2} d1={k:d[k] for k in sorted(d)}
- Yocto Project Mega-Manual 英文版 (2020官方最新合并版575页),Yocto官方文档中文版,Yocto官方文档英文版
Yocto Project Mega-Manual-(2020官方最新合并版575页)-英文版 https://market.m.taobao.com/app/idleFish-F2e/widle-t ...
- 通过抓取pintpoint2的页面信息把数据存入数据库python3
目标:对生产环境的服务质量进行量化, 解决办法:把pintpoint2里的数据转存入mysql数据库,作成报表,目前支持总请求数,错误请求数,中位数,平均数,95值(每分钟一次定时任务),其它指标可以 ...