昨天写了C#中仿效Java内SQL参数以?替代的方案,但是区分了单个参数和数组参数,而且只能支持其中的一种,不能2种情况都支持。
今天突然发现,原来可以利用params object[]参数的时候可以将数组当作参数传入,当传入对象类型的IsArray为true的时候,可以区分出单个参数还是数组参数,这样就可以在任何情况下都能将参数以?的形式替代。
由于SQL内的参数,可以是单个参数和数组参数混合的形式,因此需要属性来区分数组参数和单个参数的下标。
1 /// <summary> 2 /// 单参数下标 3 /// </summary> 4 int ParamIndex 5 { 6 get; 7 set; 8 } 9 10 /// <summary> 11 /// 数组参数下标 12 /// </summary> 13 int ArrayIndex 14 { 15 get; 16 set; 17 }
为了方便获取当前的单个参数名和数组参数名,我使用属性的Get来获取名字。
1 /// <summary> 2 /// 单参数名 3 /// </summary> 4 string SingleParam 5 { 6 get 7 { 8 return string.Format("@param_{0}", this.ParamIndex); 9 } 10 } 11 12 /// <summary> 13 /// 数组参数名 14 /// </summary> 15 string ArrayParam 16 { 17 get 18 { 19 return string.Format("@array_{0}", this.ArrayIndex); 20 } 21 }
转化的过程中,主要是对于参数替代符号?的处理,我使用正则类的Replace方法来实现。具体代码如下:
1 /// <summary> 2 /// 转化问号参数 3 /// </summary> 4 /// <param name="sql">带问号的SQL语句</param> 5 /// <param name="paramValues">参数值数组</param> 6 /// <returns></returns> 7 public SqlParameter[] CastUnknowMark(ref string sql, object[] paramValues) 8 { 9 //如存在问号参数并且参数值数组>0,则遍历每个问号参数,如参数下标超出参数值数量范围则抛出异常, 10 //如当前下标的参数值为数组,则以等同于参数值数组数量的参数替换问号参数,否则替换为单个参数 11 IList<SqlParameter> parameterList = new List<SqlParameter>(); 12 if(0 <= sql.IndexOf("?") && paramValues != null && 0 < paramValues.Length) 13 { 14 sql = new Regex(@"\?").Replace(sql, mark => 15 { 16 string paramName = this.SingleParam; 17 if(this.ParamIndex < paramValues.Length) 18 { 19 object paramValue = paramValues[this.ParamIndex]; 20 if(paramValue.GetType().IsArray) 21 { 22 IList values = paramValue as IList; 23 IList<string> paramNameList = new List<string>(); 24 foreach(object obj in values) 25 { 26 this.ArrayIndex++; 27 paramNameList.Add(this.ArrayParam); 28 parameterList.Add(new SqlParameter(this.ArrayParam, obj)); 29 } 30 paramName = string.Join(",", paramNameList.ToArray()); 31 } 32 else 33 { 34 parameterList.Add(new SqlParameter(this.SingleParam, paramValue)); 35 } 36 } 37 else 38 { 39 throw new Exception("参数值数量小于问号参数数量!"); 40 } 41 this.ParamIndex++; 42 return paramName; 43 }); 44 } 45 return parameterList.ToArray(); 46 }
个人觉得,有些想法应该尝试一下,虽然一开始写的不好,但是随着多次实践与思考,肯定能将代码写的更好,写的不好之处,请多多见谅。
|
请发表评论