切削层参数,C#中,数据交互层参数替代方案(三)

在以前的2篇文章中,个人突发奇想的仿效Java中,以?替代参数,然而在应对参数重复的情况下,需要重复填写参数,实在是挺麻烦的。
因为最近在学习和使用NHibernate,对于Hql中使用[:参数名]的方式可以解决重复参数的问题。
因为在参数键值传递的时候使用的是Hashtable,因此我们需要通过正则匹配【":\w+"】,并截取得到对应的键,获取对应的值。
代码如下:
1 Regex regMark = new Regex(@":\w+"); 2 sql = regMark.Replace(sql, s => 3 { 4 string mark = s.Value.Substring(1), paramName = string.Empty; 5 if (columns.ContainsKey(mark)) 6 { 7 //获取参数名并创建DbParameter 8 } 9 else 10 { 11 throw new NullReferenceException("不存在对应的标记键值!"); 12 } 13 return paramName; 14 });
因为参数可能会出现重复,出现重复的时候,通过对应的[:参数名],需要获取DbParameter以及Sql中的@参数名,并且我们通过Hashtable传入的值可能是数组,因此我选择使用泛型字典IDictionary>存储。
代码如下:
1 /// 2 /// 转换标记 3 /// 4 /// sql语句
5 /// 标记值Hashtable
6 /// 7 public DbParameter[] CastMark(ref string sql, Hashtable columns) 8 { 9 Regex regMark = new Regex(@":\w+"); 10 sql = regMark.Replace(sql, s => 11 { 12 string mark = s.Value.Substring(1), paramName = string.Empty; 13 if (this.dicMark.ContainsKey(mark)) 14 { 15 paramName = this.ExistMark(mark); 16 } 17 else 18 { 19 if (columns.ContainsKey(mark)) 20 { 21 paramName = this.NotExistMark(mark, columns[mark]); 22 } 23 else 24 { 25 throw new NullReferenceException("不存在对应的标记键值!"); 26 } 27 } 28 return paramName; 29 }); 30 //返回DbParameter数组 31 } 32 33 /// 34 /// 存在标记参数 35 /// 36 /// 标记
37 /// 38 string ExistMark(string mark) 39 { 40 IDictionary dicParam = this.dicMark[mark]; 41 string paramName = string.Empty; 42 if (dicParam.Count > 1) 43 { 44 paramName = string.Join(",", dicParam.Keys.ToArray()); 45 } 46 else 47 { 48 paramName = dicParam.First().Key; 49 } 50 return paramName; 51 } 52 53 /// 54 /// 不存在标记参数 55 /// 56 /// 标记
57 /// 参数值
58 /// 59 string NotExistMark(string mark, object value) 60 { 61 string paramName = string.Empty; 62 IDictionary dicParam = new Dictionary(); 63 if (value.GetType().IsArray) 64 { 65 IList values = value as IList; 66 int length = values.Count; 67 string[] names = new string[length]; 68 for (int i = 0; i < length; i++) 69 { 70 names[i] = this.GetParamName(); 71 dicParam.Add(names[i], this.CreateDbParam(names[i], values[i])); 72 } 73 paramName = string.Join(",", names); 74 } 75 else 76 { 77 paramName = this.GetParamName(); 78 dicParam.Add(paramName, this.CreateDbParam(paramName, value)); 79 } 80 dicMark.Add(mark, dicParam); 81 return paramName; 82 } 83 84 /// 85 /// 创建Db参数 86 /// 87 /// 参数名
88 /// 参数值
89 /// 90 DbParameter CreateDbParam(string paramName, object value) 91 { 92 //工厂模式,根据对应参数创建不同的DbParameter派生类 93 } 94 95 /// 96 /// 获取参数名 97 /// 98 /// 99 string GetParamName() 100 { 101 return "@Param" + index++; 102 }
到这里我们已经解决了大部分的问题了,但是每次都通过传入的参数来创建对应的DbParameter派生类也是一件挺麻烦的事情,我选择使用泛型去解决这个问题。
1 public class MarkParameter where T : DbParameter, new()
这样在类内部就可以使用T来表示DbParameter的派生类了,因此一些方法就需要修改一下了。
代码如下:
1 /// 2 /// 标记字典 3 /// 4 IDictionary> dicMark = new Dictionary>(); 5 6 7 /// 8 /// 转换标记 9 /// 10 /// sql语句
11 /// 标记值Hashtable
12 /// 13 public T[] CastMark(ref string sql, Hashtable columns) 14 { 15 //代码省略 16 } 17 18 /// 19 /// 创建Db参数 20 /// 21 /// 参数名
22 /// 参数值
23 /// 24 T CreateDbParam(string paramName, object value) 25 { 26 T param = new T(); 27 param.ParameterName = paramName; 28 param.Value = value; 29 return param; 30 }

到这里,我们就已经将一些主要的问题都解决掉了,完成了自己的sql参数替换了。
Tags:  水稳层施工方案 转换层施工方案 替代方案 储层物性参数 切削层参数

延伸阅读

最新评论

发表评论