第十五节:EF Core大数据量处理(一)之EFCore.BulkExtensions

一. 各种性能测试

   这里分享EF、EFCore、EF Core调用SQL语句 分别在1000条、1w、4w、10w下的增删改查需要的时间。

 

二. EFCore.BulkExtensions用法和性能测试

1. 说明

  通过Nuget安装程序集【EFCore.BulkExtensions】,该程序集目前版本【3.1.0】,支持CRUD操作,支持的数据库仅有:SQLServer和SQLite,它是免费开源的。

  GitHub地址:https://github.com/borisdj/EFCore.BulkExtensions

2. 用法说明

(1).Bulk相关(一条操作一个事务,均是传入实体)

 A.增加:BulkInsert

 B.修改:BulkUpdate,需要传入完整实体,不传的字段就会被更新为空

 C.增加或修改:BulkInsertOrUpdate (主键存在执行update,不存在执行insert)

 D.删除:BulkDelete 和 Truncate(删除整张表)

PS:以上方法均支持Async异步方法。

 1               //1. 增加
 2                 List<T_UserInfor> ulist1 = new List<T_UserInfor>();
 3                 for (int i = 0; i < 100; i++)
 4                 {
 5                     T_UserInfor userInfor = new T_UserInfor()
 6                     {
 7                         id = i.ToString(),
 8                         userName = "ypf",
 9                         userSex = "",
10                         userAge = 111,
11                         addTime = DateTime.Now
12                     };
13                     ulist1.Add(userInfor);
14                 }
15                 dbContext.BulkInsert(ulist1);
16 
17                 //2. 修改
18                 List<T_UserInfor> ulist2 = new List<T_UserInfor>();
19                 for (int i = 0; i < 100; i++)
20                 {
21                     //此处不写的字段就会被更新成null了
22                     T_UserInfor userInfor = new T_UserInfor()
23                     {
24                         id = i.ToString(),
25                         userName = "ypf1",
26                     };
27                     ulist2.Add(userInfor);
28                 }
29                 dbContext.BulkUpdate(ulist2);
30 
31                 //3. 删除
32                 List<T_UserInfor> ulist3 = new List<T_UserInfor>();
33                 for (int i = 0; i < 100; i++)
34                 {
35                     //此处不写的字段就会被更新成null了
36                     T_UserInfor userInfor = new T_UserInfor()
37                     {
38                         id = i.ToString(),
39                     };
40                     ulist3.Add(userInfor);
41                 }
42                 dbContext.BulkDelete(ulist3);

(2).Batch相关

 A.条件删除:BatchDelete

 B.条件更新:BatchUpdate (可以基于原有数据)

PS:以上方法均支持Async异步方法。

1  //4.条件删除
2  int count1 = dbContext.T_UserInfor.Where(u => u.id.StartsWith("2")).BatchDelete();
3 
4   //5. 条件更新
5   //5.1 基于原有数据改
6   int count2 = dbContext.T_UserInfor.Where(u => u.id.StartsWith("2")).BatchUpdate(a => new T_UserInfor() { userAge = a.userAge + 1 });
7   //5.2 直接改成新数据
8   int count3 = dbContext.T_UserInfor.Where(u => u.id.StartsWith("2")).BatchUpdate(new T_UserInfor() { userSex = "" });

(3).事务

  和正常用法一样, using(var transaction = dbContext.Database.BeginTransaction())包裹,有using的情况下, catch中不用写rollback,走完using如果报错会自动回滚。

 这种写法仅支持SQLServer,Sqlite中写法不一样

 1                 using (var transaction = dbContext.Database.BeginTransaction())
 2                 {
 3                     try
 4                     {
 5                         List<T_UserInfor> ulist1 = new List<T_UserInfor>();
 6                         for (int i = 0; i < 100; i++)
 7                         {
 8                             T_UserInfor userInfor = new T_UserInfor()
 9                             {
10                                 id = i.ToString(),
11                                 userName = "ypf",
12                                 userSex = "",
13                                 userAge = 111,
14                                 addTime = DateTime.Now
15                             };
16                             ulist1.Add(userInfor);
17                         }
18                         dbContext.BulkInsert(ulist1);
19                         int count2 = dbContext.T_UserInfor.Where(u => u.id.StartsWith("2")).BatchUpdate(a => new T_UserInfor() { id = a.id + "fsdfsdfsdfsfdsadfsadfsdfsfsafsfsdfsdfsdfsdf" });
20                         //统一提交
21                         transaction.Commit();
22                     }
23                     catch (Exception ex)
24                     {
25                         //using包裹不需要手写rollback
26                         Console.WriteLine(ex.Message);
27                     }
28                 }

(4).相关配置

  可以配置的参数有:PreserveInsertOrder, SetOutputIdentity, BatchSize, NotifyAfter, BulkCopyTimeout, EnableStreaming, UseTempDB, TrackingEntities,UseOnlyDataTable, WithHoldlock, CalculateStats, StatsInfo, PropertiesToInclude, PropertiesToExclude, UpdateByProperties, SqlBulkCopyOptions . 根据自己的情况选择使用吧

3.性能测试

      1000条    1w条    4w条      10w条

增加      0.7s     0.8s    1.2s左右     1.6s左右

条件修改                        1.2s左右

删除                       1.9s左右

说明:其他不进行测试了,上述结果足可以看出来很快。

4.封装到框架里面

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

猜你喜欢

转载自www.cnblogs.com/yaopengfei/p/12205117.html