EF架构~性能高效的批量操作(Update篇)

简介:

很多时间之长,我写了EF架构~性能高效的批量操作(Insert篇),而今天我把Update篇也写一下,这对于批量处理数据很有帮助,它解决了EF与linq to sql批量更新数据上的效率问题。

对于EF架构中的批量更新操作,需要我们为实体的导航属性进行手动的标示,因为EF生成的实体中没有一个特殊的说明,所以,我们必须要告诉系统,哪个属性是导航属性,而导航属性是我们不去进行update的。

1    /// <summary>
2     /// 属性的导航属性
3     /// </summary>
4     public class NavigationAttribute : Attribute
5     {
6 
7     }

而对于要进行批量更新的实体,我们需要为导航属性添加这个特性

1    public class User
2     {
3         public int UserID { get; set; }
4         [Navigation]
5         public User_Extension User_Extension { get; set; }
6     }

而对于我们构建批量Update语句,请看代码,它需要对导航属性进行过滤

 1         /// <summary>
 2         /// 构建Update语句串
 3         /// </summary>
 4         /// <typeparam name="TEntity"></typeparam>
 5         /// <param name="entity"></param>
 6         /// <returns></returns>
 7         private Tuple<string, object[]> CreateUpdateSQL<TEntity>(TEntity entity) where TEntity : class
 8         {
 9             if (entity == null)
10                 throw new ArgumentException("The database entity can not be null.");
11             List<string> pkList = GetPrimaryKey<TEntity>().Select(i => i.Name).ToList();
12 
13             Type entityType = entity.GetType();
14             var table = entityType.GetProperties().Where(i =>
15                 !pkList.Contains(i.Name)
16                 && i.GetValue(entity, null) != null
17                 && i.PropertyType != typeof(EntityState)
18                 && !(i.GetCustomAttributes(false).Length > 0
19                 && i.GetCustomAttributes(false).Where(j => j.GetType() == typeof(NavigationAttribute)) != null)
20                 && (i.PropertyType.IsValueType || i.PropertyType == typeof(string)) //过滤导航属性
21                  ).ToArray();
22 
23             //过滤主键,航行属性,状态属性等
24             if (pkList == null || pkList.Count == 0)
25                 throw new ArgumentException("The Table entity have not a primary key.");
26             List<object> arguments = new List<object>();
27             StringBuilder builder = new StringBuilder();
28 
29             foreach (var change in table)
30             {
31                 if (pkList.Contains(change.Name))
32                     continue;
33                 if (arguments.Count != 0)
34                     builder.Append(", ");
35                 builder.Append(change.Name + " = {" + arguments.Count + "}");
36                 if (change.PropertyType == typeof(string) || change.PropertyType == typeof(DateTime))
37                     arguments.Add("'" + change.GetValue(entity, null).ToString().Replace("'", "char(39)") + "'");
38                 else
39                     arguments.Add(change.GetValue(entity, null));
40             }
41 
42             if (builder.Length == 0)
43                 throw new Exception("没有任何属性进行更新");
44 
45             builder.Insert(0, " UPDATE " + string.Format("[{0}]", entityType.Name) + " SET ");
46 
47             builder.Append(" WHERE ");
48             bool firstPrimaryKey = true;
49 
50             foreach (var primaryField in pkList)
51             {
52                 if (firstPrimaryKey)
53                     firstPrimaryKey = false;
54                 else
55                     builder.Append(" AND ");
56 
57                 object val = entityType.GetProperty(primaryField).GetValue(entity, null);
58                 builder.Append(GetEqualStatment(primaryField, arguments.Count));
59                 arguments.Add(val);
60             }
61             return new Tuple<string, object[]>(builder.ToString(), arguments.ToArray());
62 
63         }

而对子类公开的Update方法,我们进行了一个封装,它通过操作枚举来确实你是要insert,update还是delete,看代码

 1         /// <summary>
 2         /// 执行SQL,根据SQL操作的类型
 3         /// </summary>
 4         /// <typeparam name="TEntity"></typeparam>
 5         /// <param name="list"></param>
 6         /// <param name="sqlType"></param>
 7         /// <returns></returns>
 8         protected string DoSQL<TEntity>(IEnumerable<TEntity> list, SQLType sqlType) where TEntity : class
 9         {
10             StringBuilder sqlstr = new StringBuilder();
11             switch (sqlType)
12             {
13                 case SQLType.Insert:
14                     list.ToList().ForEach(i =>
15                     {
16                         Tuple<string, object[]> sql = CreateInsertSQL(i);
17                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
18                     });
19                     break;
20                 case SQLType.Update:
21                     list.ToList().ForEach(i =>
22                     {
23                         Tuple<string, object[]> sql = CreateUpdateSQL(i);
24                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
25                     });
26                     break;
27                 case SQLType.Delete:
28                     list.ToList().ForEach(i =>
29                     {
30                         Tuple<string, object[]> sql = CreateDeleteSQL(i);
31                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
32                     });
33                     break;
34                 default:
35                     throw new ArgumentException("请输入正确的参数");
36             }
37             return sqlstr.ToString();
38         }

代码完成,这个批量操作经过测试,在速度上远远超过EF自带的方法,原因,当然是减少了与数据库交互的次数。

本文转自博客园张占岭(仓储大叔)的博客,原文链接:EF架构~性能高效的批量操作(Update篇),如需转载请自行联系原博主。

目录
相关文章
|
5月前
|
算法 编译器
【计算机架构】响应时间和吞吐量 | 相对性能 | 计算 CPU 时间 | 指令技术与 CPI | T=CC/CR, CC=IC*CPI
【计算机架构】响应时间和吞吐量 | 相对性能 | 计算 CPU 时间 | 指令技术与 CPI | T=CC/CR, CC=IC*CPI
264 0
|
1月前
|
消息中间件 存储 缓存
性能基础之大型网站技术架构模式
【2月更文挑战第15天】性能基础之大型网站技术架构模式
69 3
性能基础之大型网站技术架构模式
|
3月前
|
机器学习/深度学习 人工智能 并行计算
英伟达系列显卡大解析B100、H200、L40S、A100、A800、H100、H800、V100如何选择,含架构技术和性能对比带你解决疑惑
英伟达系列显卡大解析B100、H200、L40S、A100、A800、H100、H800、V100如何选择,含架构技术和性能对比带你解决疑惑
英伟达系列显卡大解析B100、H200、L40S、A100、A800、H100、H800、V100如何选择,含架构技术和性能对比带你解决疑惑
|
11月前
|
SQL 机器学习/深度学习 分布式计算
「大数据架构」Spark 3.0发布,重大变化,性能提升18倍
「大数据架构」Spark 3.0发布,重大变化,性能提升18倍
|
6月前
|
负载均衡 安全 微服务
服务网格和性能优化:介绍如何通过服务网格提高微服务架构的性能和可扩展性
服务网格和性能优化:介绍如何通过服务网格提高微服务架构的性能和可扩展性
57 0
|
7月前
|
架构师 关系型数据库 MySQL
掘金百万赞强制下架!MySQL性能与架构笔记,涵盖基础-优化-架构
今天给大家带来的是:简朝阳老师著的 《MySQL性能调优与架构设计》,本书是付宝架构师冯大辉、淘宝席DBA陈吉平、席DBA冯春培、网易级DBA翟振兴、搜狐级DBA叶金荣、百度级DBA吴诗展等6位数据库专作序推荐。   初级DBA到LAMP架构设计师利器。   剖析性能可用MySQL调优方,探索低本数据库系统构建之道。
|
8月前
|
数据库
国产架构完整性、可代替性和性能需要提高呀
数据库、设计软件是我们的短板,企业建构需要核心技术,国产生态需要努力
|
10月前
|
存储 SQL 数据处理
同步还是异步?ETL架构的选择,为何关系到数据处理速度和系统性能
同步还是异步?ETL架构的选择,为何关系到数据处理速度和系统性能
99 0
|
10月前
带你读《阿里云卓越架构白皮书》——1、架构设计(1)
带你读《阿里云卓越架构白皮书》——1、架构设计(1)
333 0
|
10月前
带你读《阿里云卓越架构白皮书》——1、架构设计(2)
带你读《阿里云卓越架构白皮书》——1、架构设计(2)
486 0