第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题

一. 开篇说明

  EF的性能问题一直以来经常被人所吐槽,究其原因在于“复杂的操作在生成SQL阶段耗时长,且执行效率不高”,但并不是没有办法解决,从EF本身举几个简单的优化例子:

  ①:如果仅是查询数据,并不对数据进行增、删、改操作,查询数据的时候可以取消状态追踪。

     db.TestInfor.AsNoTracking().FirstOrDefault();

  ②:用什么查什么,比如一张表有100多个字段,本次业务只需要5个字段,一定是select这5个字段,然后toList,而不是全部查询,再toList()

  ③:利用EF调用原生SQL语句或者EF调用存储过程执行。 (目前为止,没有发现该方式存在什么问题,而且性能也很快,广大博友如果认为这种方式存在什么问题,可以留言给我普及扫盲一下

  以上的几种方式,或许在一定程度上能解决一些问题,但面对大数据量的增、删、改,还是心有力而力不足。

1. 前面的章节

  前面的章节提到了Z.EntityFramework.Extensions 插件解决EF性能问题,该插件确实很nb,性能很高,而且功能很全,但是呵呵,天上没有掉馅饼的好事,该插件是收费的,如果你公司不差钱,或者你是土豪,那么强烈推荐使用该插件,性能确实不错,并且你可以直接右上角 x,不需要看该篇文章了^_^。

  但往往现实是残酷,穷人居多,这个时候就需要找免费的解决方案了,前面章节提到了 SqlBulkCopy 类(与EF没有半毛钱关系),它可以实现增加操作,不得不说,它在处理大数据量的增加的时候,确实很出色!!!。

  那么删除和更新怎么办呢?

  答案是:可以借助 Z.EntityFrameWork.Plus.EF6 才解决。

2. 进入主题

  Z.EntityFrameWork.Plus.EF6  和 Z.EntityFramework.Extensions 是同一公司的产物,该插件支持的功能很多,比如 删除、更新、缓存机制、过滤器等等,但唯独没有新增操作(都懂得,什么功能都有的话,他的兄弟 Z.EntityFramework.Extensions 怎么办?)。 

  本章节仅介绍删除和更新两个最常用的功能。 

该插件的几点说明: 

  ①:仅支持EF5、EF6、EF Core,注意不同的版本对应该插件的后缀不同,该章节使用的是EF 6.2,所以对应 Z.EntityFrameWork.Plus.EF6 

  ②:官方号称:Improve EF Performance by 2000%

  ③:可以通过Nuget进行安装

  ④:文档地址    :  http://entityframework-plus.net/batch-delete

    GitHub地址: https://github.com/zzzprojects/EntityFramework-Plus

 3. 数据库准备

  

 

二. 删除相关

1. Delete() 同步删除方法

2. DeleteAsync() 异步删除方法 <根据实际业务场景选择使用>

3. BatchSize:批次大小

  Delete和DeleteAsync两个删除方法都可以设置该参数的值:x => x.BatchSize,该参数表示一次执行的条数,默认值为4000,比如你要删除4w条数据,默认值的话,就要删除10次,

适当的提高该值,会增加删除效率,但并不代表无限增大。

特别注意:下面测试使用的Delete方法是默认块级大小4000的情况下进行测试,后面把BatchSize直接改为8w,删除8w条数据在1.6s左右

4:BatchDelayInterval:批次执行的时间间隔

  比如BatchSize=4000,BatchDelayInterval=1000,删除4w条数据,表示的意思是删除4000的时候等待1s,然后再删除。

  PS:该参数不是很常用,适用于你既需要删除很多数据,而且在批处理之间的暂停间隔继续执行CRUD操作

5:Executing:执行删除命令之前,去执行一段命令文本

  PS:根据实际场景选择使用。

下面进行性能测试:(1w条、 4w条 8w条数据的删除操作)

 (1). EF原生删除代码

复制代码

 1         /// <summary>2         /// EF普通方法测试性能3         /// </summary>4         /// <param name="db"></param>5         public static void DeleteCommon1(DbContext db)6         {7             Console.WriteLine("---------------------调用普通方法1删除--------------------------------");8             var list=db.Set<TestTwo>.Where(u=>u.id!="1").ToList();    
9              Stopwatch watch = Stopwatch.StartNew();  
10             foreach (var item in list)
11             {
12                 db.Entry(item).State = EntityState.Deleted;
13             }
14             int count = db.SaveChanges();
15             watch.Stop();
16             Console.WriteLine($"{count}条数据耗时:{watch.ElapsedMilliseconds}");
17         }

复制代码

 (2). EF调用SQL语句的代码

复制代码

 1          /// <summary>2         /// EF调用SQL语句测试删除3         /// </summary>4         /// <param name="db"></param>5         public static async void DeleteCommon2(DbContext db)6         {7             Stopwatch watch = Stopwatch.StartNew();8             string sql = "delete from TestTwo where id !='1' ";9             int count = 0;
10              //加上await,表示在这一步上异步方法执行完
11             var response = await db.Database.ExecuteSqlCommandAsync(sql);
12             count = response;
13             Console.WriteLine("异步方法已经开始执行,请耐心等待");
14             watch.Stop();
15             Console.WriteLine($"{count}条数据耗时:{watch.ElapsedMilliseconds}");
16         }

复制代码

(3). 利用该插件扩展的代码

复制代码

 1       public static void DeletePlus(DbContext db)2         {3             Console.WriteLine("---------------------调用扩展方法删除--------------------------------");4             Stopwatch watch = Stopwatch.StartNew();5             int count = db.Set<TestTwo>().Where(u => u.id != "1").Delete();6             //设置块级大小(默认4000)7             //int count = db.Set<TestTwo>().Where(u => u.id != "1").Delete(u => u.BatchSize = 80000);8             watch.Stop();9             Console.WriteLine($"{count}条数据耗时:{watch.ElapsedMilliseconds}");
10         }

复制代码

最终的测试结论(下面的时间是取三次结果的平均值):

          1w条数据     4w条数据        8w条数据

EF原生删除          76s       累哭了         累哭了

EF调SQL语句        1.152s          1.232s          1.558s

Z.Plus(默认块)      1.307s     1.982s        2.675s

  最终结论: Z.EntityFrameWork.Plus.EF6的删除比EF原生要快的多! 但EF直接调用SQL语句貌似更快哈。

 

三. 更新相关

   有了上面删除的基础,这里的更新操作就容易的多,更新的性能提升与删除类似,这里不再单独测试了,下面简单粗暴,直接介绍用法。

1. Update() 同步更新方法

2. UpdateAsync() 异步更新方法

3. Executing:上述两个方法的一个参数,表示执行更新命令之前,去执行一段命令文本(根据实际情况选择使用)

 直接上代码:

复制代码

 1        public static void UpdatePlus(DbContext db)2         {3             Console.WriteLine("---------------------调用扩展方法更新--------------------------------");4             Stopwatch watch = Stopwatch.StartNew();5             int count = db.Set<TestTwo>().Where(u => u.id != "1").Update(x => new TestTwo()6             {7                 t21 = "0",8                 t22 = "1"9             });
10             watch.Stop();
11             Console.WriteLine($"{count}条数据耗时:{watch.ElapsedMilliseconds}");
12         }

复制代码

 

  综述:该插件的使用非常简单,在使用上,可以说没有任何难度可言,很多情况下,并不是你不会解决,而是你缺少一双善于发现的眼镜。

  免费的大数据解决方案: SqlBulkCopy + Z.EntityFrameWork.Plus + EF调用SQL语句/存储过程     或许是一个不错的选择。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言怎样计算栈的长度,数据结构与算法:栈 C语言实现

栈是仅在表尾进行插入、删除操作的线性表。即栈 S (a1, a2, a3, ………,an-1, an)&#xff0c;其中表尾称为栈顶 /top&#xff0c;表头称为栈底/base。由于只能在表尾进行操作&#xff0c;因此栈的运算规则就是“后进先出”(LIFO)和线性表类似&#xff0c;栈也有两种存储结构—…

WebApi系列(从.Net 到 .Net Core)【更新】

一. 简介 1. 什么是WebApi&#xff1f; WebApi是一个很广泛的概念&#xff0c;在这里我们特指.Net平台下的Asp.Net WebApi框架&#xff0c;它是针对各种客户端(浏览器、APP等)来构建Http服务的一个框架&#xff0c;它是一种RestFul风格的开发接口的技术&#xff0c;它比WebServ…

第一节:WebApi的纯原生态的RestFul风格接口和路由规则介绍

一. 原生态接口 1. 从默认路由开始分析 在WebApiConfig.cs类中的Register方法中&#xff0c;我们可以看到默认路由如下&#xff1a; 分析&#xff1a;请求地址在 controller 前面需要加上 api/&#xff0c;controller后面没有action&#xff0c;最后有一个参数{id}&#xff0c…

第二节:如何正确使用WebApi和使用过程中的一些坑

一. 基本调用规则 1. 前提 WebApi的默认路由规则为&#xff1a;routeTemplate: "api/{controller}/{id}", 下面为我们统一将它改为 routeTemplate: "api/{controller}/{action}/{id}",这样我们在调用的时候&#xff0c;还是通过拼接方法名来识别&#xff0…

第三节:总结.Net下后端的几种请求方式(WebClient、WebRequest、HttpClient)

一. 前言 前端调用有Form表单提交&#xff0c;ajax提交&#xff0c;ajax一般是用Jquery的简化写法&#xff0c;在这里不再过多介绍&#xff1b; 后端调用大约有这些&#xff1a;WebCient、WebRequest、Httpclient、WebapiClient&#xff0c;重点探讨Get和Post请求&#xff0c;P…

android 传感器ceshi,Android代码-传感器-测试手机支持那几种传感

Android代码----传感器-----测试手机支持那几种传感一个小小Demo检测手机支持那几种传感&#xff1a;具体代码如下&#xff1a;[Java代码]DemoSensorActivity.javapackage com.example.testsensor;import java.util.List;import android.app.Activity;import android.content.C…

第四节:跨域请求的解决方案和WebApi特有的处理方式

一. 简介 前言&#xff1a; 跨域问题发生在Javascript发起Ajax调用&#xff0c;其根本原因是因为浏览器对于这种请求&#xff0c;所给予的权限是较低的&#xff0c;通常只允许调用本域中的资源&#xff0c; 除非目标服务器明确地告知它允许跨域调用。假设我们页面或者应用已在 …

手机存储android文件怎么打开,安卓手机如何打开.jio文件?

01安卓手机无法打开.jio文件&#xff0c;需要在电脑上安装久其通用数据管理平台软件打开。进入软件首页&#xff0c;点击菜单栏“装入”按钮&#xff0c;弹出“数据装入向然后导”&#xff0c;单击文件夹图标&#xff0c;在弹出“打开”窗口中选择装入数据的路径&#xff0c;单…

第五节:WebApi的三大过滤器

一. 基本说明 1. 简介&#xff1a; WebApi下的过滤器和MVC下的过滤器有一些区别,首先我们要注意的是通常建WebApi项目时&#xff0c;会自动把MVC的程序集也引入进来&#xff0c;所以我们在使用WebApi下的过滤器的时候&#xff0c;要引入“ System.Web.Http”这个程序集&#x…

android动态贴纸实现原理,人脸动态贴纸sdk算法详解,人脸动态贴纸功能如何实现...

原标题&#xff1a;人脸动态贴纸sdk算法详解&#xff0c;人脸动态贴纸功能如何实现泛娱乐行业在互联网领域中发展趋势逐渐增强&#xff0c;而直播、短视频、视频社交等作为头部产品受到了众多用户的关注和喜爱。为了能够更好的满足用户体验&#xff0c;众多APP纷纷开始接入人脸…

第六节:WebApi的部署方式(自托管)

一. 简单说明 开篇就介绍过WebApi和MVC相比&#xff0c;其中优势之一就是WebApi可以不依赖于IIS部署&#xff0c;可以自托管&#xff0c;当然这里指的是 .Net FrameWork 下的 WebApi 和 MVC 相比较&#xff0c;在.Net Core下&#xff0c;当然就另行别论。 下面我们重点介绍的就…

第七节:WebApi与Unity整合进行依赖注入和AOP的实现

一. IOC和DI 1. 通过Nuget引入Unity程序集。 PS:【版本&#xff1a;5.8.6】 2. 新建DIFactory类&#xff0c;用来读取Unity的配置文件并创建Unity容器&#xff0c;需要注意的是DIFactory类需要声明成单例。 PS&#xff1a;这里采用静态构造函数(必须是无参的)的形式来实现单…

第八节:常见安全隐患和传统的基于Session和Token的安全校验

一. 常见的安全隐患 1. SQL注入 常见的案例&#xff1a; String query "SELECT * FROM T_User WHERE userID" Request["userID"] "; 这个时候&#xff0c;只需要在传递过来的userID后面加上个&#xff1a; or 11&#xff0c;即可以获取T_User表中…

android手机设置时间设置,如何设置电信定制手机日期与时间

使用电信定制手机如A765e、A600e、A560e等的时候&#xff0c;可能会发现手机的日期和时间没法自己设置。这主要是因为手机使用电信卡时&#xff0c;会自动与电信基站进行交互并自动调节日期与时间。所以不论使用电信定制的单模或双模手机(单模是指手机只有一个卡槽&#xff0c;…

第二节 CSS入门介绍

一.背景 这里将陆续介绍前端CSS中相关知识&#xff0c;先介绍CSS2.1&#xff0c;后续会介绍CSS3的相关属性&#xff0c;通过该系列的文章&#xff0c;希望能给准备转战前端的人员一些帮助&#xff0c;同时也帮助自己梳理知识&#xff0c;文章中如有错误&#xff0c;欢迎指出。 …

三星sec.android.soagent,3.0降级2.5教程

给小白看的。下载五件套&#xff0c;odia&#xff0c;驱动&#xff0c;地址&#xff1a;http://www.samsungmembers.cn/thread-1019962-110-150.html&#xff0c;或者自己论坛搜索&#xff0c;请下载G9810ZCU2BTJA&#xff0c;别下k3最后一个版本的会出问题&#xff0c;刷机后再…

第三节 入门属性

1.七个基本属性 颜色&#xff1a;color&#xff0c;背景颜色&#xff1a;background-color&#xff0c;字体大小&#xff1a;font-size&#xff0c;加粗&#xff1a;font-weight:bold&#xff0c;倾斜&#xff1a;font-style:italic&#xff0c; 文字居中&#xff1a;text-alig…

第四节 CSS继承性和层叠性

一. 继承性 1. 含义&#xff1a;从自己开始直到所包裹的最小的元素&#xff0c;都可以继承一些特有的属性。 2. 作用范围&#xff1a; a. color、text-开头的、line-开头的、font-开头的&#xff0c;均可以继承。 b. 文字样式的&#xff0c;都能继承&#xff1b;所有关于盒子的…

html鼠标划过显示图片,jquery实现鼠标滑过小图查看大图的方法

本文实例讲述了jquery实现鼠标滑过小图查看大图的方法。分享给大家供大家参考。具体实现方法如下&#xff1a;1. CSS部分&#xff1a;ul{list-style:none;}li{float:left;margin-left:10px;}img{border:#CCCCCC solid 1px;}#max{position:absolute;display:none; /*隐藏层*/}2.…

第五节 盒子模型

1. 盒子模型的五个属性 盒模型主要涉及的属性有&#xff1a;width(宽度)、height(高度)、padding(内边距)、 border(边框)、margin(外边距)。 2. 盒子模型的两种模式 模式一&#xff1a;width盒子自身的width &#xff08;正常情况&#xff09; 模式二&#xff1a;width盒子自…