Linq中的Enumerable和Queryable
- 前言
- 正文
- 使用场合不同
- 返回类型不同
- 传递参数不同
- 总结
前言
此文章延续自C#中Linq的使用
正文
上节讲到Linq可以通过查询方法来使用,Linq中有两个命名空间,分别是System.Linq.Enumerable和System.Linq.Queryable,两个命名空间中几乎拥有相同的方法,使用方式也大致相同,如下:
int[] y = { 0, 9, 2, 3, 5 };Model1Container db = new Model1Container();// 使用Enumerable下的方法var x2 = x.Where(u => u > 0);// 使用Queryable下的方法var userSet = db.UserSet.Where(u => u.Id > 0);
使用方式相同吧,但是两个Where来自不同的命名空间:
接下来分析它们的不同点
使用场合不同
Enumerable适合在内存数据集合中使用(如数组、List等),Queryable适合在离线数据集合中使用(如EF中的dbContext中的DbSet中使用)
这你不需要自己区分,因为当数组等内存集合使用linq查询时自动使用System.Linq.Enumerable下的方法,当EF的dbContext的DbSet使用linq查询时自动使用System.Linq.Queryable下的方法,至于为什么呢?下面的不同点给出答案。
返回类型不同
上面说了VS会根据你使用的数据集合的类型来自动使用相应命名空间下的方法,这是因为VS选择了最优的使用。当返回数据集合如Where方法时,Enumerable的Where返回的IEnumerable<>,Queryable的Where返回的是IQueryable<>,这两个集合有什么区别呢?IEnumerable<>是本地集合存在内存中,而IQueryable<>属于离线集合,在使用到返回的集合IQueryable<>才加载数据,属于延迟加载
Model1Container db = new Model1Container();IQueryable<User> userSet = db.UserSet.Where(u => u.Id > 0);
上面的 db.UserSet使用了Queryable下的Where方法,这个方法需要操作数据库,但是不立刻操作数据库,而是等用到userSet时才从数据库取出数据,属于延迟加载,提高了效率。
传递参数不同
还是这一段代码:
int[] y = { 0, 9, 2, 3, 5 };Model1Container db = new Model1Container();// 使用Enumerable下的方法var x2 = x.Where(u => u > 0);// 使用Queryable下的方法var userSet = db.UserSet.Where(u => u.Id > 0);
当我们封装一些方法时需要传递参数,如上面的代码,我们想要将
u => u.Id > 0
用参数代替。
别看都是u => u.Id > 0,但是是两个不同的类型,一个是Func,一个是 Expression,如下:
Expression<Func<User, bool>> expression = u => u.Id > 0;Func<int, bool> expression2 = u => u> 0;IEnumerable<int> x2 = x.Where(expression2);IQueryable<User> userSet = db.UserSet.Where(expression);
Func和Expression将单独讲解,这里只需要知道,可以将 lambda 表达式 分配到Func<> 委托中当作参数传递;而Expression<>是将Func<>表示成数据结构。
对Func有兴趣的可以看下C#中的Func<>
总结
- Enumerable在本地集合中使用,直接加载到内存中,Queryable在操作数据库时延迟加载。
- Enumerable需要的参数是委托类型Func<>,Queryable需要的参数类型是数据结构。
Linq中的Enumerable和Queryable相关推荐
- LINQ中的Lambda表达式
Lambda Expressions in LINQ 在第12章,我提到可以用lambda表达式定义内联的委托定义.在如下表达式中: customer => customer.FirstName ...
- 用日志记录LINQ中的所有增删改的SQL语句的方法
我们知道LINQ中的增删改都要调用SubmitChanges方法,我们记录所有SQL的方式就是重写(override)DataContext中的SubmitChanges方法,为了避免每次修改dbml ...
- Linq中的Where与SkipWhile
本文将介绍Linq中的Where与SkipWhile的用法,有时我们容易混淆它们.下面来看一个简单的UnitTest: [TestMethod] public void TestSkipWhileAn ...
- LINQ中ForEach方法的使用
标签: linq 2016-06-25 12:47 409人阅读 评论(0) 收藏 举报分类: LINQ(5) 我の原创(113) 版权声明:本文为博主原创文章,未经博主允许不得转载.LINQ中For ...
- Linq中的group by多表多字段,Sum求和
Linq中的group by多表多字段,Sum求和 //Line to Sql 写法var data = (from a in Itemsgroup a by new { a.GroupId, a.I ...
- C#8.0: 在 LINQ 中支持异步的 IAsyncEnumerableT接口
C# 8.0中,提供了一种新的IAsyncEnumerable<T>接口,在对集合进行迭代时,支持异步操作.比如在读取文本中的多行字符串时,如果读取每行字符串的时候使用同步方法,那么会导致 ...
- Linq中string转int的方法
Linq中string转int的方法 在做批量删除时,需把一串id值所对应的数据删除,调试出现问题: Linq语句中如果使用ToString()进行类型转换,编译时不会报错,但执行时会出现如下错误: ...
- 转载Linq中GroupBy方法的使用总结
Group在SQL经常使用,通常是对一个字段或者多个字段分组,求其总和,均值等. Linq中的Groupby方法也有这种功能.具体实现看代码: 假设有如下的一个数据集: public class St ...
- linq中let关键字学习
linq中let关键字就是对子查询的一个别名,let子句用于在查询中添加一个新的局部变量,使其在后面的查询中可见. linq中let关键字实例 1.传统下的子查询与LET关键字的区别 C# 代码 ...
最新文章
- POJ 2029 Get Many Persimmon Trees
- php 打印变量内存地址_Python合集之Python变量
- java研发自测报告_开发自测方法探讨
- 视觉slam十四讲ch6曲线拟合 代码注释(笔记版)
- JS中的map函数(会改变不是基本类型的数组的值)
- 统计测序数据reads数和碱基数的几种方法
- 面试精讲之面试考点及大厂真题 - 分布式专栏 09 缓存必问:Reids持久化,高可用集群
- git获得当前分支url_笔记本拿出来!软件工程师必须要知道的Git命令语句大汇总...
- linux禁止扫描端口,公网的服务器如何禁止别人扫描端口
- asp .net 多文件上传(二)
- Linux下nautilus的右键快捷菜单项设置
- python重新安装numpy_Python-如何重新安装NumPy
- 亚马逊全站点、全类目产品爬取,支持批量品牌注册查询,独家技术防屏蔽节省大量选品分析时间,全自动无人值守运行
- 从 MVC 到使用 ASP.NET Core 6.0 的最小 API
- Python + Scrapy 小小爬虫有大大梦想
- 路由器信号分为2.4G和5G,有什么区别?
- B. Sereja and Mirroring
- kali初使用之zsh
- python npv 计算公式_Python numpy 中常用的数据运算
- python发送文件_Python发送邮件(最全)