即使用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进行存档.那 ...
随机推荐
- SuperMap iClient 7C——网络客户端GIS开发平台 产品新特性
SuperMap iClient 7C是空间信息和服务的可视化交互开发平台,是SuperMap服务器系列产品的统一客户端.产品基于统一的架构体系,面向Web端和移动端提供了多种类型的SDK开发包,帮助 ...
- Android-socket服务端断重启后,android客户端自动重连
今天研究这个问题搞了整整一天啊!终于出来了,不过我没有多大的成就感,为什么呢?因为这不是我的劳动成果.同样的问题,我却没想出来!心塞的很啊…… 不过还是要给大家分享一下,希望给大家带来帮助! 先声明一 ...
- iOS开发之巧用Block和代理方法结合来传值
好久没写技术博客了,因为996的工作周期已经持续好几个月了.每天晚上回家都没有太多精力学习很多其他的东西,而且很多时候是接着完善工作的项目的模块开发.所以博客停歇了这么久,更新率也低了不少,今天补充一 ...
- docker'部署
环境:ubuntu-14.04.4-server-amd64 1.更换阿里云源 备份源配置文件: $ sudo cp /etc/apt/sources.list /etc/apt/sources.li ...
- PS技巧:如何优雅的抠公章?
搞设计的很苦逼,整天面对各种各样任务,除了修图.排版外,还时不时会有些另类需求.这时如果掌握一些小技巧就不用临时抱佛脚啦. 下面献上一计:教大家怎么用PS抠公章.有需要的拿去,PS:不要干坏事吆! 效 ...
- 八爪鱼招标网的百度权重升为2了,独立IP也从0快速发展为1000
自八爪鱼招标网上线以来,本着以客户一切利益为出发点,坚持提供国内首个免费招标信息平台为目标,经过各位同事不断地努力,不断收集客户各种各样的招标.采购实际需求,与政府.事业单位及中小型企业一对一的沟 ...
- Build 2015 Beijing & Windows 10 China Geek Challenge
6月5日,借着Build 2015在北京召开分会的东风,参加了这次由微软中国举办的Windows 10中国开发者极客挑战赛. 白天是Build 2015课程,学习了Windows 10最新的技术,包括 ...
- 【hive】——Hive sql语法详解
Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQL查 ...
- EF6 Create Different DataContext on runtime(运行时改变连接字符串)
引言 在使用EF时,有时我们需要在程序运行过程中动态更改EF的连接字符串,但不幸的时EF是否对 ConfigurationManager.RefreshSection("xxx" ...
- github 和 github for windows 学习使用总结
github 是最大的开源项目托管平台,是一个网站.但是它不仅仅只能托管开源项目或代码,还能作为我们备份重要资料的平台,更重要的是我们可以通过这个平台来学习和获取别人的代码,避免重复造轮子,还可以多人 ...