一. 各种性能测试
这里分享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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。