【问题标题】:ArgumentException on Adding multiple Parameters in Stored Procedure在存储过程中添加多个参数时出现 ArgumentException
【发布时间】:2016-02-09 06:28:42
【问题描述】:

我正在尝试通过添加三个参数来调用存储过程,但在添加第二个参数时出现以下 ArgumentException

SqlParameter 已被另一个包含 SqlParameterCollection

这里是sn-p的代码:

using (IDbCommand cmd =Idbconnection.CreateCommand())
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = "usp_Get_Products";
    IDataParameter param = cmd.CreateParameter();
    param.ParameterName = "@rvcName";
    param.Value = productName;
    cmd.Parameters.Add(param);
    param.ParameterName = "@rvcCode";
    param.Value = productCode;
    cmd.Parameters.Add(param);
    param.ParameterName = "@riProductTypeID";
    param.Value = productTypeID;
    cmd.Parameters.Add(param);
    using (IDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            Product product = new Product(reader["Name"].ToString(), reader["Code"].ToString(), reader["Description"].ToString(), (DateTime)reader["DateCreated"], Convert.ToInt32(reader["pkProductID"]), Convert.ToInt32(reader["ProductTypeID"]), reader["ProductTypeName"].ToString());
            products.Add(product);
        }
    }
}

【问题讨论】:

    标签: c# stored-procedures parameters


    【解决方案1】:

    您收到错误是因为 param 已添加到参数集合中。在您的代码中,您只需更改现有对象的值,然后尝试重新添加它。

    您需要为集合中的每个参数创建一个新参数对象实例

    IDataParameter param = cmd.CreateParameter();
    param.ParameterName = "@rvcName";
    param.Value = productName;
    cmd.Parameters.Add(param);
    
    param = cmd.CreateParameter(); //create a new instance for the next parameter
    param.ParameterName = "@rvcCode";
    param.Value = productCode;
    cmd.Parameters.Add(param);
    
    param = cmd.CreateParameter(); //create a new instance for the next parameter
    param.ParameterName = "@riProductTypeID";
    param.Value = productTypeID;
    cmd.Parameters.Add(param);
    

    根据您的评论,同意这不是很干燥。但是,除非您在某处拥有现有的元数据,否则可能不值得花精力创建一次性元组列表来循环它们并创建不同的对象。

    您可以使用现有的AddWithValue 方法(但您必须小心null 的值,否则参数将变得无足轻重!):

    cmd.Parameters.AddWithValue("@rvcName", (object)productName ?? DBNull.Value);
    cmd.Parameters.AddWithValue("@rvcCode", (object)productCode ?? DBNull.Value);
    cmd.Parameters.AddWithValue("@riProductTypeID", (object)productTypeID ?? DBNull.Value);
    

    同样,还没有完全干燥,所以你可以用你自己的方法包装它:

    static void AddParameterWithValue(this IDbCommand cmd, string paramName, object value)
    {
        if(paramName == null)
            throw new ArgumentNullException(nameof(paramName));
    
        if(string.IsNullOrWhiteSpace(paramName))
        {
            throw new ArgumentOutOfRangeException(
                nameof(paramName), 
                paramName, 
                "Parameter name cannot be empty");
        }
    
        cmd.Parameters.AddWithValue(paramName, value ?? DBNull.Value);
    }
    

    【讨论】:

    • 就没有其他类似循环的方式了吗?看起来有点乱
    【解决方案2】:

    你可以使用foreach循环

    using (IDbCommand cmd =Idbconnection.CreateCommand())
    {
        foreach(var item in your data)
        {
            IDataParameter param = cmd.CreateParameter();
            param.ParameterName = item.(your data here for ParameterName)
            param.Value = item.productCode;
            cmd.Parameters.Add(param);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 2017-09-26
      相关资源
      最近更新 更多