当重复使用带有事务的SqlCommand时,我是否应该调用Parameters.Clear方法?

9

我正在使用ADO.NET手动编写事务。 我正在使用的示例重复使用SqlCommand,这似乎是一个好主意。

但是,我已经向我的命令添加了参数。

我的问题是:在以下代码中,command.Parameters.Clear()是否正确? 还是我做错了?

using (var connection = new SqlConnection(EomAppCommon.EomAppSettings.ConnStr))
{
    connection.Open();
    SqlTransaction transaction = connection.BeginTransaction();
    SqlCommand command = connection.CreateCommand();
    command.Transaction = transaction;
    try
    {
        foreach (var itemIDs in this.SelectedItemIds)
        {
            command.CommandText = "UPDATE Item SET payment_method_id = @batchID WHERE id in (@itemIDs)";
            // IS THE FOLLOWING CORRECT?
            command.Parameters.Clear();

            command.Parameters.Add(new SqlParameter("@batchID", batchID));
            command.Parameters.Add(new SqlParameter("@itemIDs", itemIDs));
            command.ExecuteNonQuery();
        }
        transaction.Commit();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Failed to update payment batches, rolling back." + ex.Message);
        try
        {
            transaction.Rollback();
        }
        catch (Exception exRollback)
        {
            if (!(exRollback is InvalidOperationException)) // connection closed or transaction already rolled back on the server.
            {
                MessageBox.Show("Failed to roll back. " + exRollback.Message);
            }
        }
    }
}

为什么不在循环内部创建命令呢?或者创建一个可以一次性完成所有更新的SQL语句,完全避免循环的出现? - Damien_The_Unbeliever
2个回答

13

既然您要重复执行相同的查询,那么清除它们是不必要的 - 您可以在循环外部添加参数,然后在循环内部仅填充它们。

try
{
    command.CommandText = "UPDATE Item SET payment_method_id = @batchID WHERE id in (@itemIDs)";
    command.Parameters.Add(new SqlParameter("@batchID", 0));
    command.Parameters.Add(new SqlParameter("@itemIDs", ""));

    foreach (var itemIDs in this.SelectedItemIds)
    {
        command.Parameters["@batchID"].Value = batchID;
        command.Parameters["@itemIDs"].Value = itemIDs;
        command.ExecuteNonQuery();
    }
    transaction.Commit();
}

注意 - 你不能像你这里使用参数来处理IN操作符 - 这样是行不通的。


是的,我刚发现关于IN子句的事情,感谢提供链接。 - Aaron Anodide
除了额外的处理之外,清除并重新添加它们还有其他不利因素吗?不清除它们也会使代码变得不够DRY。 - Lukas

1
在这种情况下,您需要它就像您需要设置新的参数值一样,因此是正确的。
顺便说一下,移动。
command.CommandText = ".."

因为它从未改变,所以它也在循环之外。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接