61

我可以有效地使用这种方法吗?

using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString))
{
    cmd.Connection.Open();
    // set up parameters and CommandType to StoredProcedure etc. etc.
    cmd.ExecuteNonQuery();
}

我担心的是:SqlCommand 的 Dispose 方法(退出 using 块时调用)是否会关闭底层 SqlConnection 对象?

4

4 回答 4

123

不,处置SqlCommand不会影响连接。更好的方法是也将其包装SqlConnection在 using 块中:

using (SqlConnection conn = new SqlConnection(connstring))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand(cmdstring, conn))
    {
        cmd.ExecuteNonQuery();
    }
}

否则,连接不会因为使用它的命令被处置而改变(也许这就是你想要的?)。但请记住,连接也应该被处理掉,而且处理起来可能比命令更重要。

编辑:

我刚刚测试了这个:

SqlConnection conn = new SqlConnection(connstring);
conn.Open();

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 1", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 2", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

conn.Dispose();  

第一个命令在 using 块退出时被释放。连接仍然打开并且对第二个命令有好处。

因此,处理命令绝对不会处理它正在使用的连接。

于 2008-09-13T22:20:59.667 回答
11

SqlCommand.Dispose 是不够的,因为许多 SqlCommand(s) 可以(重新)使用相同的 SqlConnection。将注意力集中在 SqlConnection 上。

于 2008-10-08T22:48:42.697 回答
1

很多地方都犯了这个错误,甚至是 MS 自己的文档。请记住 - 在 DB 世界中,几乎所有内容都由非托管资源支持,因此几乎所有内容都实现了 IDisposable。除非编译器另有说明,否则假设一个类可以。将您的命令包装在 using 中。将您的连接包装在 using 中。从 DbProvider 创建连接(从 DbProviderFactories.GetFactory 获取),并从连接中创建命令,这样如果您更改底层数据库,只需更改对 DBPF.GetFactory 的调用。因此,您的代码最终应该看起来漂亮且对称:

var provider = DbProviderFactories.GetFactory("System.Data.SqlClient");// Or MS.Data.SqlClient
using (var connection = provider.CreateConnection())
{
    connection.ConnectionString = "...";
    using (var command = connection.CreateCommand())
    {
        command.CommandText = "...";
        connection.Open();

        using (var reader = command.ExecuteReader())
        {
...
        }
    }
}
于 2020-01-07T20:55:54.460 回答
-12

我使用这种模式。我在我的应用程序的某个地方有这个私有方法:

private void DisposeCommand(SqlCommand cmd)
{
    try
    {
        if (cmd != null)
        {
            if (cmd.Connection != null)
            {
                cmd.Connection.Close();
                cmd.Connection.Dispose();
            }
            cmd.Dispose();
        }
    }
    catch { } //don't blow up
}

然后我总是在 try 块中创建 SQL 命令和连接(但没有被包装在 using 块中)并且总是有一个 finally 块:

    finally
    {
        DisposeCommand(cmd);
    }

作为命令对象的属性的连接对象在这种情况下使 using 块很尴尬 - 但是这种模式可以完成工作而不会弄乱你的代码。

于 2011-04-13T18:52:08.473 回答