之前的博客里面已经有这个ADOHelper的一个简易版本(注:此扩展不是SqlHelper),然后这两天看到有位同志在博客园贴了个简易的拼接Update Sql方法,想想自己以前也写过一个版本,但因为上份工作离职后,未将此部分代码保留,所以又将这些代码重写了一遍,并做了一些相关扩展,该部分扩展不适用于所有关系型数据库(ACCESS就不适用,可以进行参数扩展使之适用,只是个人不打算这么做),但至少适用于MSSQL,Oracle,MySql,以下是相关代码
using System.Data; using System.Data.Common; /// <summary> /// 数据相关的帮助类 /// </summary> public static class ADOHelper { /// <summary> /// 从DataReader中读取可空对象 /// </summary> /// <typeparam name="T">泛型T</typeparam> /// <param name="dr">IDataReader</param> /// <param name="key">Key</param> /// <returns></returns> public static Nullable<T> GetNullable<T>(this IDataRecord dr, string key) where T : struct { return dr[key] == null || dr[key] == DBNull.Value ? (Nullable<T>)null : (T)dr[key]; } /// <summary> /// 当DataReader读取对象为空时,返回defaultValue /// </summary> /// <typeparam name="T">泛型T</typeparam> /// <param name="dr">IDataReader</param> /// <param name="key">Key</param> /// <param name="defaultValue">当取到的数据为DBNull时,应当返回的默认值</param> /// <returns></returns> public static T GetDefaultWhileNullable<T>(this IDataRecord dr, string key, T defaultValue = default(T)) { return dr[key] == null || dr[key] == DBNull.Value ? defaultValue : (T)dr[key]; } /// <summary> /// 从DataReader中读取字符串并消除前后空白字符 /// </summary> /// <param name="dr">IDataReader</param> /// <param name="key">Key</param> /// <returns></returns> public static string GetTrimedString(this IDataRecord dr, string key) { return dr[key].ToString().Trim(); } /// <summary> /// 将数组转换为IN对应的SQL(返回值不包含小括号),返回格式@P1,@P2,@P3 /// </summary> /// <typeparam name="T1">数据类型</typeparam> /// <typeparam name="T2">Sql参数类型</typeparam> /// <param name="items"></param> /// <param name="parameters"></param> /// <param name="key"></param> /// <param name="dbType"></param> /// <param name="paramterPrefix"></param> /// <returns></returns> public static string GetInSql<T1, T2>(this IEnumerable<T1> items, out IList<T2> parameters, string key = "p", DbType? dbType = null, char paramterPrefix = '@') where T2 : DbParameter, new() { if (items == null || !items.Any()) { throw new ArgumentNullException(); } StringBuilder tmp = new StringBuilder(); parameters = new List<T2>(); int i = 0; foreach (T1 item in items) { string k = string.Format("{0}{1}{2}", paramterPrefix, key, i); tmp.Append(','); tmp.Append(k); T2 param = new T2(); param.ParameterName = k; param.Value = item; if (dbType.HasValue) { param.DbType = dbType.Value; } parameters.Add(new T2() { ParameterName = k, Value = item }); i++; } tmp.Remove(0, 1); return tmp.ToString(); } /// <summary> /// 如果当前值为null,则返回DbNull,以防止Sql参数不被传递的问题 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static object GetDbNullWhileNull(this object obj) { if (obj == null) { return DBNull.Value; } return obj; } /// <summary> /// 获取简单的更新Sql /// </summary> /// <typeparam name="T">Sql参数类型</typeparam> /// <param name="tableName">关系型数据库表名</param> /// <param name="updateDic">要更新的字段集合</param> /// <param name="keyDic">where条件集合,可传null值,此时表示更新所有数据</param> /// <param name="parameters">与返回Sql对应的DbParameter集合</param> /// <param name="paramterPrefix">Sql参数前缀</param> /// <returns></returns> public static string GetUpdateSql<T>(this string tableName, IDictionary<string, object> updateDic, IDictionary<string, object> keyDic, out IList<T> parameters, char paramterPrefix = '@') where T : DbParameter, new() { if (string.IsNullOrWhiteSpace(tableName) || updateDic == null || updateDic.Count == 0) { throw new ArgumentNullException(); } StringBuilder sql = new StringBuilder(); parameters = new List<T>(); sql.Append("UPDATE "); sql.AppendLine(tableName); sql.AppendLine("SET"); Action<IDictionary<string, object>, IList<T>, string> act = (dic, list, joinStr) => { foreach (var kv in dic) { sql.Append(kv.Key); sql.Append('='); sql.Append(paramterPrefix); sql.Append(kv.Key); sql.Append(joinStr); T param = new T(); param.ParameterName = string.Format("{0}{1}", paramterPrefix, kv.Key); param.Value = kv.Value.GetDbNullWhileNull(); //param.DbType可以在方法执行结束后根据索引获取再进行设置 list.Add(param);//在匿名方法、lambda 表达式或查询表达式的内部不能使用 ref 或 out 参数,所以要声明list } }; act(updateDic, parameters, ","); sql.Remove(sql.Length - 1, 1); if (keyDic != null && keyDic.Count > 0) { sql.AppendLine(); sql.AppendLine("WHERE"); act(keyDic, parameters, " AND "); sql.Remove(sql.Length - 5, 5); } return sql.ToString(); } }拼接Sql扩展对应的测试代码
IDictionary<string, object> updateDic = new Dictionary<string, object>() { {"FieldInt",1}, {"FieldString","test"}, {"FieldDateTime",DateTime.Now} }; IDictionary<string, object> keyDic = null; IList<SqlParameter> parameter; string tableName = "TableName"; string sql = tableName.GetUpdateSql(updateDic, keyDic, out parameter); Console.WriteLine(sql); keyDic = new Dictionary<string, object>() { {"KeyInt",99}, {"KeyString","55"} }; Console.WriteLine("###################################"); sql = tableName.GetUpdateSql(updateDic, keyDic, out parameter, ':'); Console.WriteLine(sql); Console.WriteLine("--------------------------------"); IEnumerable<int> arr = Enumerable.Range(1, 10); sql = arr.GetInSql(out parameter, paramterPrefix: ':'); Console.WriteLine(sql);