/// <summary> /// 根据指定的DbCommand创建匹配的ParaNameBuilder, /// 框架直接三种DbCommand类型:SqlCommand, OdbcCommand, OleDbCommand /// </summary> /// <param name="command"></param> /// <returns></returns> public ParaNameBuilder GetBuilder(DbCommand command) { if (command == null) { throw new ArgumentNullException("command"); } // SQLSERVER最常用,所以优先判断 if (command is System.Data.SqlClient.SqlCommand) { return(SqlParaNameBuilder.Instance); } if (command is System.Data.Odbc.OdbcCommand || command is System.Data.OleDb.OleDbCommand ) { return(OleDbParaNameBuilder.Instance); } // 尝试获取框架外部的ParaNameBuilder实现 ParaNameBuilder builder = TryGetOtherBuilder(command); // 默认就返回与SQLSERVER兼容的ParaNameBuilder,因为有不少数据库驱动也是支持的 return(builder ?? SqlParaNameBuilder.Instance); }
private void AddParameter(string name, object value) { DbParameter parameter = _command.CreateParameter(); parameter.ParameterName = ParaNameBuilder.GetParaName(name); parameter.Value = value ?? DBNull.Value; _command.Parameters.Add(parameter); }
private void SetDbParameter(string name, DbParameter parameter) { if (string.IsNullOrEmpty(parameter.ParameterName)) { parameter.ParameterName = ParaNameBuilder.GetParaName(name); } // else 不检查参数的名称是否匹配,由调用者保证。 _command.Parameters.Add(parameter); }
internal void AddQueryParameter(QueryParameter p) { string name = "p" + GetNextParamIndex().ToString(); // SQL语句中拼入参数占位符 _sqlBuidler.Append(ParaNameBuilder.GetPlaceholder(name)); // 参数集合中添加命令参数 AddParameter(name, p.Value); }
/// <summary> /// 根据指定的name/value,给命令参数赋值,或者处理【占位符参数】 /// </summary> /// <param name="name"></param> /// <param name="value"></param> private void SetParameter(string name, object value) { // 根据属性名称,查找参数集合有没有对应的参数 string pname = ParaNameBuilder.GetParaName(name); DbParameter p = GetParameter(pname); if (p != null) { // 注意:在调用 XmlCommand 时,匿名对象的值不能是DbParameter, // 因为XmlCommand已经定义过命令参数,调用时只需要赋值即可(与CPQuery不同) p.Value = value ?? DBNull.Value; return; } // 如果参数集合没有匹配的参数,就尝试从命令文本中查找 {name} ,并做替换处理。 string placeholder = "{" + name + "}"; int j = _command.CommandText.IndexOf(placeholder, StringComparison.OrdinalIgnoreCase); if (j > 0) { // 处理【占位符参数】操作,有3种场景: // 1、字符串替换,例如:表名占符,允许一个XmlCommand操作多个表 // 2、IN 子句替换 // 3、查询条件替换,用CPQuery构造一个子查询或者查询片段 if (value is CPQuery) { SetQueryParameter(placeholder, (CPQuery)value); } else if (value is ICollection) { SetInArrayParameter(placeholder, (ICollection)value); } else { SetReplaceParameter(placeholder, value.ToString()); } } // 2018-01-04 注释下面的抛异常代码,原因: // 存在一种场景:实体中包含的某个属性是数据表的自增列,此时在XmlCommand是没有定义的, // 当使用实体做为参数时,就会运行到这里,但是这种情况又是正常的。 //else // // 如果没有匹配的命令参数,也找不到匹配的【占位符参数】,就抛出异常告之调用者 // throw new ArgumentException(string.Format( // "传入的参数对象中,属性 {0} 没有在MXL定义对应的参数名。", name)); }
private DbParameter[] GetParameters(object parameterObject) { if (parameterObject == null) { return(null); } PropertyInfo[] properties = parameterObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); DbParameter[] parameters = new DbParameter[properties.Length]; int index = 0; foreach (PropertyInfo property in properties) { object value = property.FastGetValue(parameterObject); DbParameter parameter = null; if (value == null || value == DBNull.Value) { parameter = _command.CreateParameter(); parameter.ParameterName = ParaNameBuilder.GetParaName(property.Name); parameter.Value = DBNull.Value; } if (value is DbParameter) { // 允许包含DbParameter,用于构造输出参数 parameter = value as DbParameter; if (string.IsNullOrEmpty(parameter.ParameterName)) { parameter.ParameterName = ParaNameBuilder.GetParaName(property.Name); } } else { parameter = _command.CreateParameter(); parameter.ParameterName = ParaNameBuilder.GetParaName(property.Name); parameter.Value = value; } parameters[index] = parameter; index++; } return(parameters); }
/// <summary> /// 设置 IN 参数,参数名称格式要求:{parameterName} /// 例如:select * from t1 where rid in ( {parameterName} ) /// </summary> /// <param name="name"></param> /// <param name="collection"></param> private void SetInArrayParameters(string name, ICollection collection) { //if( collection == null || collection.Count == 0 ) // throw new ArgumentNullException("collection"); StringBuilder sb = new StringBuilder(128); // 优先检查 int[], Guid[] 类型,并转成SQL语句中的一部分 // 因为这些强类型的数据本身是安全的,不存在注入,就不转换成命令参数。 ArrayToString(collection, sb); if (sb.Length == 0) // 如果不是 int[], Guid[] ,就转换成命令参数 { foreach (object obj in collection) { string paraName = "x" + GetNextParamIndex().ToString(); this.AddParameter(paraName, obj); if (sb.Length > 0) { sb.Append(','); } sb.Append(ParaNameBuilder.GetPlaceholder(paraName)); } } if (sb.Length == 0) { sb.Append("NULL"); } if (name == null) // 用于LINQ查询中的IN场景 { _sqlBuidler.Append(sb.ToString()); } else // 用于替换占位符场景 { string placeholder = "{" + name + "}"; _sqlBuidler.Replace(placeholder, sb.ToString()); } }
private void SetInArrayParameter(string placeholder, ICollection collection) { StringBuilder sb = new StringBuilder(128); // 优先检查 int[], Guid[] 类型,并转成SQL语句中的一部分 // 因为这些强类型的数据本身是安全的,不存在注入,就不转换成命令参数。 CPQuery.ArrayToString(collection, sb); if (sb.Length == 0) // 如果不是 int[], Guid[] ,就转换成命令参数 { foreach (object obj in collection) { string name = "x" + (_paramIndex++).ToString(); DbParameter parameter = _command.CreateParameter(); parameter.ParameterName = ParaNameBuilder.GetParaName(name); parameter.Value = obj; _command.Parameters.Add(parameter); if (sb.Length > 0) { sb.Append(','); } sb.Append(ParaNameBuilder.GetPlaceholder(name)); } } if (sb.Length == 0) { sb.Append("NULL"); } _command.CommandText = _command.CommandText.Replace(placeholder, sb.ToString()); }