博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EF架构~性能高效的批量操作(Update篇)
阅读量:5993 次
发布时间:2019-06-20

本文共 4484 字,大约阅读时间需要 14 分钟。

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

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

1    /// 2     /// 属性的导航属性3     /// 4     public class NavigationAttribute : Attribute5     {6 7     }

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

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

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

1         ///  2         /// 构建Update语句串 3         ///  4         /// 
5 /// 6 ///
7 private Tuple
CreateUpdateSQL
(TEntity entity) where TEntity : class 8 { 9 if (entity == null)10 throw new ArgumentException("The database entity can not be null.");11 List
pkList = GetPrimaryKey
().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) != null17 && i.PropertyType != typeof(EntityState)18 && !(i.GetCustomAttributes(false).Length > 019 && 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
arguments = new List();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 else39 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 else55 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
(builder.ToString(), arguments.ToArray());62 63 }

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

1         ///  2         /// 执行SQL,根据SQL操作的类型 3         ///  4         /// 
5 /// 6 /// 7 ///
8 protected string DoSQL
(IEnumerable
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
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
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
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自带的方法,原因,当然是减少了与数据库交互的次数。

转载地址:http://qgvlx.baihongyu.com/

你可能感兴趣的文章
C#调用C++写的Dll时的运行时错误解决
查看>>
Ubuntu下如何进入终端命令行
查看>>
步步为营UML建模系列五、时序图(Squence diagram)
查看>>
【转】iOS平台安装包介绍
查看>>
GIS工具-shp浏览器
查看>>
.NET Core微服务之基于Steeltoe使用Hystrix熔断保护与监控
查看>>
软件调试的艺术(Linux Unix平台软件调试权威著作)
查看>>
知道力——彻底超越执行力的25条职场新思维
查看>>
转---一个提高渲染效率的小技巧
查看>>
Entity Framework 4.1正式版发布,徐汇区网站设计
查看>>
【JOURNAL】天井组诗之七 - 来生
查看>>
strtok()和strtok_r()
查看>>
关于override,new 那点事
查看>>
awk用法小结
查看>>
C++运算符重载
查看>>
论文笔记之:Playing Atari with Deep Reinforcement Learning
查看>>
iBeacon
查看>>
多线程编程之四——线程的同步
查看>>
存储过程,触发器,游标
查看>>
php.ini中allow_call_time_pass_reference参数的意思
查看>>