IQueryable和IEnumerable的区别
2015-06-19 09:30
676 查看
在新的系统框架中,常会用到IQueryable和IEnumerable这两个接口,经过一段时间的接触和学习,对于这两种类型的区别有了初步的理解。我们先来看一下这两种接口的定义:
IEnumerable接口
公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代。也就是说:实现了此接口的object,就可以直接使用foreach遍历此object;
IQueryable 接口
它继承 IEnumerable 接口,而因为.net版本加入Linq和IQueryable后,使得IEnumerable不再那么单调,变得更加强大和丰富。
为了区别两个接口,我们通过一个实际的例子来解释一下。
跟踪一下代码,看一下这两段在执行时所生成的SQL代码:
第一段,返回IQueryable接口类型:
第二段,返回IEnumerable接口类型:
通过上面两个例子我总结了一下,IQueryable接口与IEnumberable接口的区别:
IEnumerable<T> 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,而IQueryable<T> 是将Skip ,take 这些方法表达式翻译成T-SQL语句之后再向SQL服务器发送命令,它并不是把所有数据都加载到内存里来才进行条件过滤。
IEnumerable接口
公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代。也就是说:实现了此接口的object,就可以直接使用foreach遍历此object;
IQueryable 接口
它继承 IEnumerable 接口,而因为.net版本加入Linq和IQueryable后,使得IEnumerable不再那么单调,变得更加强大和丰富。
为了区别两个接口,我们通过一个实际的例子来解释一下。
[TestMethod] public void LinqTest() { var db = new SecurityRepositoryContext(new HSLogger()); var ur = new UserRepository(db); //查询的结果放入IQueryable接口的集合中 IQueryable<User> querys = (from c in db.Context.Set<User>() orderby c.Code select c).Skip<User>(2).Take<User>(2); //注意这个AsEnumerable<User>()在分页查询之前,先将其转换成IEnumerable类型 IEnumerable<User> enumers = (from c in db.Context.Set<User>() orderby c.Code select c).AsEnumerable<User>().Skip<User>(2).Take<User>(2); //因为启用了延迟加载机制,所以下面调用一下,才会真正去读取数据库 foreach (var c in querys) { //TODO } foreach (var c in enumers) { //TODO } }
跟踪一下代码,看一下这两段在执行时所生成的SQL代码:
第一段,返回IQueryable接口类型:
SELECT [Extent1].[Id] AS [Id], [Extent1].[Code] AS [Code], [Extent1].[Name] AS [Name], [Extent1].[Status] AS [Status], [Extent1].[IsOnline] AS [IsOnline], [Extent1].[SystemVersion] AS [SystemVersion], [Extent1].[CreatedBy] AS [CreatedBy], [Extent1].[CreatedOn] AS [CreatedOn], [Extent1].[ModifiedBy] AS [ModifiedBy], [Extent1].[ModifiedOn] AS [ModifiedOn], [Extent1].[VersionNumber] AS [VersionNumber] FROM [dbo].[User] AS [Extent1] ORDER BY [Extent1].[Code] ASC OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY
第二段,返回IEnumerable接口类型:
SELECT [Extent1].[Id] AS [Id], [Extent1].[Code] AS [Code], [Extent1].[Name] AS [Name], [Extent1].[Status] AS [Status], [Extent1].[IsOnline] AS [IsOnline], [Extent1].[SystemVersion] AS [SystemVersion], [Extent1].[CreatedBy] AS [CreatedBy], [Extent1].[CreatedOn] AS [CreatedOn], [Extent1].[ModifiedBy] AS [ModifiedBy], [Extent1].[ModifiedOn] AS [ModifiedOn], [Extent1].[VersionNumber] AS [VersionNumber] FROM [dbo].[User] AS [Extent1] ORDER BY [Extent1].[Code] ASC
通过上面两个例子我总结了一下,IQueryable接口与IEnumberable接口的区别:
IEnumerable<T> 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,而IQueryable<T> 是将Skip ,take 这些方法表达式翻译成T-SQL语句之后再向SQL服务器发送命令,它并不是把所有数据都加载到内存里来才进行条件过滤。
相关文章推荐
- request 获取参数
- 为Angular-UEditor增加工具栏属性
- NGUI 的ScrollView如何让item居中
- 【Android开发经验】Android举UI设计经验
- 【iOS】UIStackView官方文档翻译
- SQL Server查询计划sys.dm_exec_text_query_plan
- UGUI 实现文本打字效果
- UITableView学习笔记
- Leetcode Implement stack using queues
- [Druid:数据库连接池] removeAbandoned 功能引发的血案 避免单业务执行时间超时
- UIScrollView的使用大全
- leetcode 225: Implement Stack using Queues
- EasyUI上传图片,前台预览,后台读取
- Nearest Sequence(lcs)
- Lucene知识总结(Query篇)
- BlockingQueue的使用
- 成为设计师的五项技能!第一招~~
- herbnate session.createSQLQuery(sql) 和 session.createQuery(sql)使用
- UINavigationController设置透明背景
- uiautomakor工具安装常见问题