C#中,数据交互层参数替代方案
在以前的2篇文章中,个人突发奇想的仿效Java中,以?替代参数,然而在应对参数重复的情况下,需要重复填写参数,实在是挺麻烦的。
因为最近在学习和使用NHibernate,对于Hql中使用[:参数名]的方式可以解决重复参数的问题。
因为在参数键值传递的时候使用的是Hashtable,因此我们需要通过正则匹配【":\w+"】,并截取得到对应的键,获取对应的值。
代码如下:
1Regex regMark = newRegex(@":\w+");
2sql = regMark.Replace(sql, s =>
3{
4 stringmark = s.Value.Substring(1), paramName = string.Empty;
5 if(columns.ContainsKey(mark))
6 {
7 //获取参数名并创建DbParameter
8 }
9 else
10 {
11 thrownewNullReferenceException("不存在对应的标记键值!");
12 }
13 returnparamName;
14});
因为参数可能会出现重复,出现重复的时候,通过对应的[:参数名],需要获取DbParameter以及Sql中的@参数名,并且我们通过Hashtable传入的值可能是数组,因此我选择使用泛型字典IDictionary<string, IDictionary<string, DbParameter>>存储。
代码如下:
1///<summary>
2///转换标记
3///</summary>
4///<param name="sql">sql语句</param>
5///<param name="columns">标记值Hashtable</param>
6///<returns></returns>
7publicDbParameter[] CastMark(refstringsql, Hashtable columns)
8{
9 Regex regMark = newRegex(@":\w+");
10 sql = regMark.Replace(sql, s =>
11 {
12 stringmark = 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 thrownewNullReferenceException("不存在对应的标记键值!");
26 }
27 }
28 returnparamName;
29 });
30 //返回DbParameter数组
31}
32
33///<summary>
34///存在标记参数
35///</summary>
36///<param name="mark">标记</param>
37///<returns></returns>
38stringExistMark(stringmark)
39{
40 IDictionary<string, T> dicParam = this.dicMark[mark];
41 stringparamName = 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 returnparamName;
51}
52
53///<summary>
54///不存在标记参数
55///</summary>
56///<param name="mark">标记</param>
57///<param name="value">参数值</param>
58///<returns></returns>
59stringNotExistMark(stringmark, objectvalue)
60{
61 stringparamName = string.Empty;
62 IDictionary<string, DbParameter> dicParam = newDictionary<string, DbParameter>();
63 if(value.GetType().IsArray)
64 {
65 IList values = value asIList;
66 intlength = values.Count;
67 string[] names = newstring[length];
68 for(inti = 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 returnparamName;
82}
83
84///<summary>
85///创建Db参数
86///</summary>
87///<param name="paramName">参数名</param>
88///<param name="value">参数值</param>
89///<returns></returns>
90DbParameter CreateDbParam(stringparamName, objectvalue)
91{
92 //工厂模式,根据对应参数创建不同的DbParameter派生类
93}
94
95///<summary>
96///获取参数名
97///</summary>
98///<returns></returns>
99stringGetParamName()
100{
101 return"@Param"+ index++;
102}
到这里我们已经解决了大部分的问题了,但是每次都
补充:软件开发 , C# ,