当前位置: 首页 > news >正文

Entity Framework中IQueryable, IEnumerable, IList的差别

应用Entity Framework等ORM框架的时辰,SQL对于应用者来说是透明的,往往很多人也不关怀ORM所生成的SQL,然而体系呈现机能题目的时辰就必须存眷生成的SQL以发明题目地点。

 

应用过Toplink的伴侣知道很只要设置日记打印级别=FINE就可以设备使之生成的SQL在办事器中打印出来,Entiry Framework没有那么荣幸,在以前要检测生成SQL的独一办法是SQL Server Profiler,但应用起来并不便利,成果也不克不及主动保存到文件中。

 

Tracing and Caching Provider Wrappers for Entity Framework是Entity Framework Team新推出的开源SQL追踪和二级缓存的解决规划。道理是在负责履行具体SQL语句的data provider(SqlClient或者其他Client)之上插入了一层WrappingProvider,用于监控DbCommand.uteReader(), uteScalar() and uteNonQuery(),将Sql号令输出到指定介质或者将查询成果缓存起来以重用。

 

 

应用办法很简单,下载源代码编译后将dll添加到项目中,新加一个类WrappedNorthWindEntities持续原有的Entities即可,详见源代码中的示例。

 

 

下面我们应用EF Wrapper来监测Entify Framework中IQueryable, IEnumerable和IList所生成的SQL。

 

TestIQueryable 

private static void TestIQueryable()
{

using (var ctx = new WrappedNorthWindEntities())
{
IQueryable<Product> expression = ctx.Products.Take(5);
IQueryable<Product> products = expression.Take(2); // A 不履行SQL


Console.WriteLine(products.Count());          // B SELECT COUNT(1) FROM ( SELECT TOP (2) * FROM ( SELECT TOP (5) * FROM [dbo].[Products] ))
Console.WriteLine(products.Count());          // C SELECT COUNT(1) FROM ( SELECT TOP (2) * FROM ( SELECT TOP (5) * FROM [dbo].[Products] ))
foreach (Product p in products)             // D SELECT TOP (2) * FROM ( SELECT TOP (5) * FROM [dbo].[Products]
{
Console.WriteLine(p.ProductName);
}
foreach (Product p in products)             // E SELECT TOP (2) * FROM ( SELECT TOP (5) * FROM [dbo].[Products] )
{
Console.WriteLine(p.ProductName);
}
}
}

 

 

 

TestIEnumerable 

private static void TestIEnumerable()
{
using (var ctx = new WrappedNorthWindEntities())
{
IEnumerable<Product> expression = ctx.Products.Take(5).AsEnumerable();
IEnumerable<Product> products = expression.Take(2); // A 不履行SQL
Console.WriteLine(products.Count());          // B SELECT TOP (5) * FROM [dbo].[Products]
Console.WriteLine(products.Count());          // C SELECT TOP (5) * FROM [dbo].[Products]
foreach (Product p in products)             // D SELECT TOP (5) * FROM [dbo].[Products]
{
Console.WriteLine(p.ProductName);
}
foreach (Product p in products)             // E SELECT TOP (5) * FROM [dbo].[Products]
{
Console.WriteLine(p.ProductName);
}
}
}

 

 

 

TestIList 

private static void TestIList()
{
using (var ctx = new WrappedNorthWindEntities())
{
var expression = ctx.Products.Take(5);
IList<Product> products = expression.Take(2).ToList(); // A SELECT TOP (2) * FROM ( SELECT TOP (5) * FROM [dbo].[Products]


Console.WriteLine(products.Count());           // B 不履行SQL
Console.WriteLine(products.Count());           // C 不履行SQL
foreach (Product p in products)              // D 不履行SQL
{
Console.WriteLine(p.ProductName);
}
foreach (Product p in products)             // E 不履行SQL
{
Console.WriteLine(p.ProductName);
}
}
}

 

 由上可见



    1. IQueryable和IEnumerable都是延时履行(Deferred ution)的,而IList是即时履行(Eager ution)

 

    1. IQueryable和IEnumerable在每次履行时都必须连接数据库读取,而IList读取一次后,今后各次都不需连接数据库。前两者很轻易造成反复读取,机能低下,并且可能激发数据不一致性

 

    1. IQueryable和IEnumerable的差别:IEnumberalb应用的是LINQ to Object体式格式,它会将AsEnumerable()时对应的所有记录都先加载到内存,然后在此根蒂根基上再履行后来的Query。所以上述TestIEnumerable例子中履行的SQL是" top(5) ...",然后在内存中选择前两笔记录返回。



IQueryable激发数据不一致性的例子:记录总数和记录详情两者本应一致,但因为IQueryable前后两次读取数据库,成果是实际有10笔记录,却输出11条详情。

 

 

 

IQueryable Data Inconsistancy 

    IQueryable<Product> expression = ctx.Products.All();
//开端的时辰数据库product表中有10笔记录, count = 10
int count = products.Count();
Console.WriteLine("Count of products:"+count);

        
//此时另一过程添加一个产品进数据库

    //会从头读取数据库并输出11个产品名称
foreach (Product p in products)
{
Console.WriteLine(p.ProductName);
}

 

 

 

基于机能和数据一致性这两点,我们应用IQueryable时必须谨慎,而在大多半景象下我们应应用IList。



    • 当你筹算即速应用查询后的成果(比如轮回作逻辑处理惩罚或者填充到一个table/grid中),并且你不介怀该查询会即时履行,应用ToList()

 

    • 当你欲望查询后的成果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的办法),或者你欲望该查询延时履行,应用AsQueryable()

相关文章:

  • oracle序列详解
  • Win C盘扩容
  • 下载网站-资源共享
  • 汇编逻辑运算指令
  • 应用系统之间数据传输的几种方式
  • 使用SCOM 2012监控网络
  • ASP.NET MVC在服务端把异步上传的图片裁剪成不同尺寸分别保存,并设置上传目录的尺寸限制...
  • 有关AngularJS请求Web API资源的思路
  • C# 调用 C++ Dll 类库的传参问题
  • 转:fastText原理及实践(达观数据王江)
  • 算法问题实战策略
  • BZOJ 2584: [Wc2012]memory(扫描线+线段树)
  • 用最新NLP库Flair做文本分类
  • ASP.NET Core 2.0 : 三. 项目结构
  • 前后端分离架构中接口测试最佳实践
  • 「译」Node.js Streams 基础
  • Angular Elements 及其运作原理
  • bootstrap创建登录注册页面
  • emacs初体验
  • flutter的key在widget list的作用以及必要性
  • Hibernate【inverse和cascade属性】知识要点
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java面向对象及其三大特征
  • k个最大的数及变种小结
  • PhantomJS 安装
  • PHP 7 修改了什么呢 -- 2
  • Selenium实战教程系列(二)---元素定位
  • 创建一个Struts2项目maven 方式
  • 给初学者:JavaScript 中数组操作注意点
  • 聊聊flink的TableFactory
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 如何利用MongoDB打造TOP榜小程序
  • 用简单代码看卷积组块发展
  • Spring Batch JSON 支持
  • 阿里云ACE认证之理解CDN技术
  • #QT(串口助手-界面)
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (Git) gitignore基础使用
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (附源码)计算机毕业设计高校学生选课系统
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (三分钟)速览传统边缘检测算子
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)iOS字体
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .libPaths()设置包加载目录
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .net 微服务 服务保护 自动重试 Polly
  • .net 无限分类