SqlCommand.Dispose 是否关闭连接?

发布于 2024-07-04 09:59:47 字数 353 浏览 7 评论 0原文

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

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 对象?

Can I use this approach efficiently?

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

My concern is : Will the Dispose method of the SqlCommand (which is called when exiting the using block) close the underlying SqlConnection object or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小忆控 2024-07-11 09:59:47

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

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

否则,由于使用它的 Command 已被释放,Connection 不会发生变化(也许这就是您想要的? )。 但请记住,连接应该
也可以被处理掉,并且可能比命令更重要。

编辑:

我刚刚测试了这一点:

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 块时第一个命令被释放。 连接仍然打开并且适合第二个命令。

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

No, Disposing of the SqlCommand will not effect the Connection. A better approach would be to also wrap the SqlConnection in a using block as well:

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

Otherwise, the Connection is unchanged by the fact that a Command that was using it was disposed (maybe that is what you want?). But keep in mind, that a Connection should
be disposed of as well, and likely more important to dispose of than a command.

EDIT:

I just tested this:

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

The first command was disposed when the using block was exited. The connection was still open and good for the second command.

So, disposing of the command definitely does not dispose of the connection it was using.

过期情话 2024-07-11 09:59:47

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

SqlCommand.Dispose will not be sufficient because many SqlCommand(s) can (re)use the same SqlConnection. Center your focus on the SqlConnection.

萌面超妹 2024-07-11 09:59:47

很多地方都犯了这个错误,甚至是微软自己的文档。 请记住 - 在数据库世界中,几乎所有东西都由非托管资源支持,因此几乎所有东西都实现了 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())
        {
...
        }
    }
}

Soooo many places get this wrong, even MS' own documentation. Just remember - in DB world, almost everything is backed by an unmanaged resource, so almost everything implements IDisposable. Assume a class does unless the compiler tells you otherwise.
Wrap your command in a using. Wrap your connection in a using. Create your connection off a DbProvider (get that from DbProviderFactories.GetFactory), and your command off your connection so that if you change your underlying DB, you only need to change the call to DBPF.GetFactory.
So your code should end up looking nice and symmetrical:

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())
        {
...
        }
    }
}
羁客 2024-07-11 09:59:47

我用这个模式。 我的应用程序中的某处有这个私有方法:

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

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

I use this pattern. I have this private method somewhere in my app:

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
}

Then I always create SQL commands and connections in a try block (but without being wrapped in a using block) and always have a finally block as:

    finally
    {
        DisposeCommand(cmd);
    }

The connection object being a property of the command object makes a using block awkward in this situation - but this pattern gets the job done without cluttering up your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文