即使用ADO.NET,也要轻量级动态生成更新SQL,比Ormlite性能更高
先上测试结果:
- //测试1000次针对同一个表同一个字段更新,比Ormlite平均快2.34倍
- //生成SQL+ExecuteNonQuery Ormlite 倍数
- //6513ms 15158ms 2.327
- //6461ms 15303ms 2.369
- //6624ms 15424ms 2.329
- //6591ms 15468ms 2.347
- //测试1000次针对同一个表同一个字段更新,比EF平均快1.68倍
- //生成SQL+ExecuteNonQuery EF 倍数
- //6622ms 11113ms 1.678
- //6577ms 11117ms 1.690
- //6756ms 11258ms 1.666
- //6603ms 11184ms 1.694
不管出于什么原因,有时候框架人员摒弃了NH或EF,而使用原生数据库访问对象。
为了优美的编程,用上我写的轻量级动态生成更新SQL扩展方法吧
还记得在EF中只更新修改过的字段时,我们这么写:
- var e = db.Entry(d);
- e.State = EntityState.Unchanged;
- d.UploadTime = DateTime.Now;
- e.Property("UploadTime").IsModified = true;
- db.SaveChanges();
目的是,使生成的更新SQL只更新UploadTime字段,否则会更新所有字段,那么就需要先查询一遍再更新。
既然提到数据仓储,我们更新一个实体在数据层最好只有一个方法,但是一个更新的SQL能满足要求吗?
出于以上目的,我写了这样的轻量级扩展方法:
- /// <summary>
- ///
- /// </summary>
- public static class SqlStringEx
- {
- #region 静态私有成员
- private static object _obj = new object();
- private static Dictionary<int, PropertyInfo[]> propertiesCache = new Dictionary<int, PropertyInfo[]>();
- /// <summary>
- /// 从缓存中获取属性信息
- /// </summary>
- /// <param name="t"></param>
- /// <returns></returns>
- private static PropertyInfo[] GetPropertiesFromCache(Type t)
- {
- var code = t.GetHashCode();
- if (!propertiesCache.ContainsKey(code))
- {
- lock (_obj)
- {
- if (!propertiesCache.ContainsKey(code))
- {
- propertiesCache.Add(code, t.GetProperties());
- }
- }
- }
- return propertiesCache[code];
- }
- #endregion
- /// <summary>
- /// 根据实体模型的赋值情况,动态生成更新SQL。避免要先获取再保存,或者避免按需写多个更新SQL
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="t"></param>
- /// <param name="tableName">数据表名称</param>
- /// <param name="conditionColumnName">更新时条件列名称,该列名需包含在parameters中</param>
- /// <param name="parameters"></param>
- /// <returns></returns>
- public static string GenerateUpdateSql<T>(this T t, string tableName, string conditionColumnName, out List<SqlParameter> parameters)
- where T : new()
- {
- parameters = new List<SqlParameter>();
- StringBuilder res = new StringBuilder();
- res.AppendFormat("update {0} set ", tableName);
- var props = GetPropertiesFromCache(t.GetType());
- string wherePart = null;
- foreach (PropertyInfo item in props)
- {
- var propVal = item.GetValue(t, null);
- var hasValue = propVal != null && !propVal.Equals();
- if (hasValue)
- {
- var filedname = item.GetFieldName();
- parameters.Add(new SqlParameter { Value = propVal, ParameterName = filedname });
- if (filedname.Equals(conditionColumnName.ToLower()))
- {
- wherePart = string.Format(" where {0}=@{0} ", filedname);
- }
- else
- {
- res.AppendFormat(" {0}=@{0} ,", filedname);
- }
- }
- }
- res.Remove(res.Length - , );
- res.Append(wherePart);
- return res.ToString();
- }
- }
其中的GetFieldName()方法见上一篇
有了这个方法,数据层一个实体就只需要一个更新的方法,也不需要自己去拼接更新的SQL了。
- List<SqlParameter> parameters =null;
- var saveSql = model.GenerateUpdateSql("TableName", "ID", out parameters);
注意,model的属性的默认值分两种,值类型默认值为0,引用类型和非空值类型的默认值是null,当model属性的值不是默认值的时候会参与值的更新。
saveSql就是我们要更新的SQL,parameters是对应更新的参数。ID参数也可以是别的列,但在model中作为条件的列的值不能为默认值。
有没有很方便,欢迎抛砖。
虽然重复造轮子,但方便性是不是可以弥补一切。
性能要求高的,请慎重考虑,因为内部使用了反射。但是性能总的来说比Ormlite更快,执行1000次更新,本扩展方法耗时6513毫秒,而Ormlite耗时15158毫秒。
EF相比Ormlite更快:
即使用ADO.NET,也要轻量级动态生成更新SQL,比Ormlite性能更高的更多相关文章
- graphicview和widgets没本质区别。它只是更轻量级,更灵活,性能更高的widgets
graphicview和widgets没本质区别.它只是更轻量级,更灵活,性能更高的widgets.核心就是把widgets变成了更轻量级的graphicitem,把QWidget的各种事件转换成了g ...
- 寻找性能更优秀的动态 Getter 和 Setter 方案
反射获取 PropertyInfo 可以对对象的属性值进行读取或者写入,但是这样性能不好.所以,我们需要更快的方案. 方案说明 就是用表达式编译一个 Action<TObj,TValue> ...
- 百度echart如何动态生成图表
百度echart如何动态生成图表 一.总结 一句话总结: clear hideloading setOption 主要是下面三行代码: myChart.clear(); //清空画布myChart.h ...
- Aop动态生成代理类时支持带参数构造函数
一.背景 在某些情况下,我们需要植入AOP代码的类并没有默认构造函数.那么此时动态生成的代理类也需要相同签名的构造函数,并且内部调用原始类的构造函数.自己折腾了1晚上没搞定,现在搞定了发出来供大家一起 ...
- dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来
dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...
- ABP(现代ASP.NET样板开发框架)系列之20、ABP展现层——动态生成WebApi
点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerplate Project (ASP.N ...
- 【.NET深呼吸】Zip文件操作(2):动态生成Zip文档
通过前面一篇烂文的介绍,大伙儿知道,ZipArchive类表示一个zip文档实例,除了用上一篇文章中所列的方法来读写zip文件外,还可以直接通过ZipArchive类,动态生成zip文件. 文件流操作 ...
- jquery动态生成的元素添加事件的方法
动态生成的元素如果要添加事件,要写成 $(document).on("click", "#txtName", function() { alert(this.v ...
- 利用Java动态生成 PDF 文档
利用Java动态生成 PDF 文档,则需要开源的API.首先我们先想象需求,在企业应用中,客户会提出一些复杂的需求,比如会针对具体的业务,构建比较典型的具备文档性质的内容,一般会导出PDF进行存档.那 ...
随机推荐
- Android中的AlertDialog使用示例二(普通选项对话框)
在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,AlertDialog实现方法为建造者模式. ...
- PHP魔术常量
与J2E相比PHP没有九个内置对象,但他有八个魔术变量分别是: '__LINE__' 文件中的当前行号. '__FILE__ 文件的完整路径和文件名. '__DIR__' 文件所在的目录. '__FU ...
- 关于iOS10
iOS10相册相机闪退bughttp://www.jianshu.com/p/5085430b029fiOS 10 因苹果健康导致闪退 crashhttp://www.jianshu.com/p/54 ...
- iOS开发之巧用Block和代理方法结合来传值
好久没写技术博客了,因为996的工作周期已经持续好几个月了.每天晚上回家都没有太多精力学习很多其他的东西,而且很多时候是接着完善工作的项目的模块开发.所以博客停歇了这么久,更新率也低了不少,今天补充一 ...
- js 多选 反选
//$(".435__1").attr("checked", true); //$(".435__0").removeAttr(" ...
- Storm基础
Storm基本概念 Storm是一个开源的实时计算系统,它提供了一系列的基本元素用于进行计算:Topology.Stream.Spout.Bolt等等. 在Storm中,一个实时应用的计算任务被打包作 ...
- SQL SERVER 2012链接到SQL SERVER 2000的问题解决案例
前几天在在桦仔的SQLSERVER走起微信公众帐号看到一篇文章MS SQL Server2014链接MS SQL Server 2000,当时手机上囫囵吞枣看了个大概,知道是由于SQL SERVER ...
- winform窗体(二)——控件
一.窗体的事件 每一个窗体都有一个事件,这个窗体加载完成之后执行哪一段代码 位置:1)右键属性→事件→load 双击进入 2)双击窗体任意一个位置进入 删除事件:先将事件页面里面的挂好的事件删除,再删 ...
- web.xml is missing and <failOnMissingWebXml> is set to true 错误解决办法
对web项目的解决方案: 右击项目——>Java EE Tools——>Generate Deployment Descriptor Stub. 然后系统会在src/main/webapp ...
- mysql内置函数大全
mysql 字符串函数用法集合 ASCII(str)返回字符串str的最左面字符的ASCII代码值. mysql> select ascii('d'); +------------+ | asc ...