处理SqlCommand

Disposing SqlCommand

因为 SqlCommand 实现了 IDisposable,我通常会按如下方式处理 ADO 查询。

using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
    // Execute command, etc. here
}

但是,如果我需要在单个连接期间执行多个命令怎么办?我真的需要为每个命令创建一个新的 using 块吗?

我从 Microsoft 找到的示例不使用 usingSqlCommand(甚至调用 Dispose())。关于处置 SqlCommand 的最佳做法是什么?

using 语句确保即使在调用对象的方法时发生异常,也会调用 Dispose。您可以通过将对象放在 try 块中然后在 finally 块中调用 Dispose 来获得相同的结果。

在这种情况下,您对每个命令块使用 using

using (SqlConnection connection = new SqlConnection(connectionString))
{
   using (SqlCommand cmd1= new SqlCommand(query1, connection))
   {
   }

   using (SqlCommand cmd2= new SqlCommand(query2, connection))
   {
   }  
}

当然,最好的做法是处理它们。

using (SqlConnection connection = new SqlConnection(connectionString))
{
   connection.Open();

   using (SqlCommand command1 = new SqlCommand(query1, connection))
   {
      // Execute command, etc. here
   }

   using (SqlCommand command2 = new SqlCommand(query2, connection))
   {
      // Execute command, etc. here
   }

   using (SqlCommand command3 = new SqlCommand(query3, connection))
   {
      // Execute command, etc. here
   }
}

MSDN 可能不会显示它,因为在 SqlCommand 的情况下它是 not really needed。但在我看来,微软不在每个实现 IDdisosable 的对象上使用这种模式是不好的,因为人们不习惯它。

最佳做法是,如果它实现了 IDisposable,那么就对它进行 Dispose()。 事实上,示例 here 都调用了 Dispose。有皱纹:

第一个示例打开 SqlDataReader,在 finally 子句中对命令调用 .Close()。事实上,.Close 只是 .Dispose() 的包装器(并且不再出现在文档中)。 Jonathan Wood 在他的评论中指出 Close 在 reader.这是错误的。

对于同一连接上的多个呼叫,您可以:

  1. Re-use 一个命令(在一个使用中声明)。我不喜欢这个 我自己,但那只是我:我发现它......丑陋。
  2. 在多次使用中使用多个命令。这就是我要做的。

'Best Practice' 有点乱。从来没有一致认为 A 吹捧为最佳实践的人比 B 推荐的人更好,更不用说 C、D 或 E 了。请自行判断。

不,你没有。有两种方法可以将您的多个命令捆绑在一个连接和命令中。

第一种是仅重用现有的 CMD 对象,但根据需要更改 CommandText 和其他 CMD.properties。

using (SqlConnection con = new SqlConnection(connectionString)) {

    con.Open();

    using (SqlCommand cmd = new SqlCommand(query1, con)) {
        // cmd.CommandType = CommandType.xxxxx
        // add any parameters
        // Execute()

        cmd.CommandText = query2;
        // reset CommandType if needed
        // adjust parameters if needed
        // Execute()

        cmd.CommandText = query 3;
        // reset CommandType if needed
        // adjust parameters if needed
        // Execute()
    }
    con.Close();
}

第二种方法是在数据库服务器上创建一个存储过程并在一个CMD对象中调用它

-- Database
CREATE PROCEDURE schema.sproc_CommandBatch (
    -- any variables here
) AS
BEGIN
    -- query 1

    -- query 2

    -- query 3
END
GO


// C#
using (SqlConnection con = new SqlConnection(connectionString)) {

    con.Open();

    using (SqlCommand cmd = new SqlCommand("schema.sproc_CommandBatch", con)) {
        // cmd.CommandType = CommandType.StoredProcedure
        // add any parameters
        // Execute()
    }
    con.Close();
}