即使用ADO.NET,也要轻量级动态生成更新SQL

不管出于什么原因,有时候框架人员摒弃了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能满足要求吗?

出于以上目的,我写了这样的轻量级扩展方法:

    public static class SqlStringEx
    {
        /// <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 = t.GetType().GetProperties();
            string wherePart = null;
            foreach (PropertyInfo item in props)
            {
                var propVal = item.GetValue(t, null);
                var hasValue = propVal != null && !propVal.Equals(0);
                if (hasValue)
                {
                    var filedname = item.GetFieldName();
                    parameters.Add(new SqlParameter { Value = propVal, ParameterName = filedname });
                    if (filedname.Equals(conditionColumnName.ToLower()))
                    {
                        wherePart = string.Format(" where {0}[email protected]{0} ", filedname);
                    }
                    else
                    {
                        res.AppendFormat(" {0}[email protected]{0} ,", filedname);
                    }
                }
            }
            res.Remove(res.Length - 1, 1);
            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中作为条件的列的值不能为默认值。

有没有很方便,欢迎抛砖。

虽然重复造轮子,但方便性是不是可以弥补一切。

性能要求高的,请慎重考虑,因为内部使用了反射。

时间: 2024-07-29 00:01:59

即使用ADO.NET,也要轻量级动态生成更新SQL的相关文章

如何查看存储过程中动态生成的sql

今天在工作中遇到那么一个需求,要查看存储过程中生成的sql,以便和实际的业务需求核对. 经过多方查询,想到如下办法: 1.在存储过程中凡是涉及到execute immediate mysql的地方,加上DBMS_OUTPUT.PUT_LINE(mysql);同时为了减少运行时间将execute immediate mysql注释. 2.如果因为mysql字符过长,报string buffer is too small,那么采用另外一种方式,事先定义v_pos Number := 1;然后通过以下

C# 动态生成WebService,无需添加引用

C#项目调用WebService是很常见的现象,但一旦修改链接地址就需要重新更新引用很是麻烦,这里跟大家分享一个通过地址,无需添加引用动态生成Webservice的小方法 方法类: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ServiceModel; 6 using System.ServiceModel.Channels

C++实现根据类名动态生成类对象

在开发后台服务的过程中,我们常常需要从数据库中取数据,并将数据缓存在本地中,另外,我们的服务还需要有更新数据的能力:包括定时的主动更新以及数据库数据更新时服务收到通知的被动更新. 之前在需要用到以上功能的时候,模仿着组内通用的数据Cache部分的代码来写,十分方便,基本上只需要自己写两个类:一个是取数据并缓存数据的类XXXData,一个是扇出数据的类XXXFetcher. 在需要使用数据的时候,通过: FetcherFactory::getFetcher<XXXFetcher>() 即可获取一

[搬运自我的CSDN博客] python抓取javascript动态生成HTML内容的实践

<注:CSDN博客在美国访问特别卡,所以转移到cnblogs来发文章> 本实验在Ubuntu14.04上完成.使用的浏览器是火狐(Firefox 33.0),python版本是2.7.6. 大家都知道用urllib配合正则表达式抓取静态HTML的内容很方便,但是如果网页中有javascript动态生成的内容,urllib就无能为力了. 此时我们要借助一个额外的工具:selenium.它的工作原理是操纵(火狐)浏览器浏览目标网页,等待网页中的javascript全部执行完毕后再对HTML源码进行

动态生成二级菜单

现在越来越多的用到二级甚至多级菜单,前台菜单的显示,手动指定也越来越不能满足要求,所以,动态生成菜单是必须的 思路 + 示例代码(以二级菜单为例) 先取出一级菜单内容值,接下来遍历一级菜单,将其id当做本次检索的parentid,将与之对应的二级菜单值获取到, 并加入到当前数组中(后台) 二层循环,当获取一个值时,检查其对于的二级菜单项是否有数据,有的话,则输出来,没有则跳过(前台) 以PHP后台为例 $res = mysql_query('*** where parentid = 0');  

nginx利用image_filter动态生成缩略图

原文:http://www.open-open.com/lib/view/open1416193847945.html "我现在是有些图片需要生成缩略图,这个现在加了image_filter这个已经实现了,但我不知道怎么样才能访问我上传的原图" 刚开始觉得也不太好弄,让他用程序区处理,实际上稍微动脑筋分析一下也可以不修改程序实现动态生成缩略图且能够访问原图. 前提是需要定好图片的访问规则. 先来看一下什么是nginx的image filter模块. HttpImageFilterMod

动态生成随机背景色表格

<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>动态生成随机背景色表格</title> <style> table{margin-top:20px;width:800px;border:1px solid #ddd;border-collapse:collapse;} td{border:1px solid #ddd;padding:

Android动态生成表格

最近刚刚学习完Android的五大布局,现在我们进一步深入学习,尝试做一个动态生成表格功能的例子 样式布局代码如下: 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4

js动态生成数据列表

我们通常会使用table标签来展示数据内容,由于需要展示的数据内容是随时更换的,所以不可能将展示的数据列表写死在html写死在页面中,而是需要我们根据后台传来的数据随时更换,这个时候就需要我们使用js来动态生成表格. 首先我们需要先写好页面的样式. html部分 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; chars