在存储过程中添加多个参数的ArgumentException

时间:2016-02-09 06:28:42

标签: c# stored-procedures parameters

我试图通过添加三个参数来调用存储过程但是在添加第二个参数时我得到以下ArgumentException

  

SqlParameter已被另一个包含   SqlParameterCollection

以下是代码段:

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);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您收到错误,因为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);
}

答案 1 :(得分:0)

您可以使用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);
    }
}