SqlConnection.Close()需要在Using语句内部吗?

49

我正在使用这段代码:

    public void InsertMember(Member member)
    {
        string INSERT = "INSERT INTO Members (Name, Surname, EntryDate) VALUES (@Name, @Surname, @EntryDate)";

        using (sqlConnection = new SqlConnection(sqlConnectionString_WORK))
        {
            sqlConnection.Open();

            using (SqlCommand sqlCommand = new SqlCommand(INSERT, sqlConnection))
            {
                sqlCommand.Parameters.Add("@Name", SqlDbType.VarChar).Value = member.Name;
                sqlCommand.Parameters.Add("@Surname", SqlDbType.VarChar).Value = member.Surname;
                sqlCommand.Parameters.Add("@EntryDate", SqlDbType.Date).Value = member.EntryDate;

                sqlCommand.ExecuteNonQuery();
            }
        }
    }

如果我在释放sqlConnection之前不添加sqlConnection.Close();是不正确的吗?我的意思是,它没有显示任何错误,也没有任何问题。关闭它是否更好?如果是,为什么?


4
即使出现异常,using语句也会释放连接,因此你其实不需要在那里调用Close方法。 - V4Vendetta
7个回答

61
这里不需要关闭(或处理); using块会为您处理。
根据Microsoft Learn的说明:

The following example creates a SqlConnection, opens it, [and] displays some of its properties. The connection is automatically closed at the end of the using block.

private static void OpenSqlConnection(string connectionString) 
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
        Console.WriteLine("State: {0}", connection.State);
    } 
}

这是关于 Close(),而不是 Dispose() :) - Matten
2
代码在倒数第二个右花括号“}”之前有一个connection.Close(),这样可以吗?当using块尝试关闭已被代码关闭的连接时,会抛出异常吗? - variable

11
使用语句确保在调用对象的方法时,即使发生异常,也会调用Dispose。您可以通过将对象放入try块中,然后在finally块中调用Dispose来实现相同的结果;事实上,这就是编译器对using语句的翻译。MSDN
所以最终您的代码行
using (sqlConnection = new SqlConnection(sqlConnectionString_WORK))

编译器会将 try finally 块中的 IDisposable 对象调用转换为普通的块。


11
根据Microsoft Learn文档中的Close方法所述:
引用: 你必须通过调用CloseDispose来显式关闭连接。 CloseDispose在功能上是等效的。
因此,调用Dispose(甚至可以使用using隐式调用)将涵盖您的基础,就像这样。
值得注意的是,我认为,尽管与您的情况无关,但当事物被包装在using语句中时,Close将始终被有效调用 - 如果省略并且发生异常而没有正确的try/catch/finally处理,则可能不会发生这种情况。

1
在这个例子中,它说明:下面的示例创建了一个SqlConnection,打开它,并显示了它的一些属性。连接在using块结束时自动关闭。 - Darren
@DarrenDavies 没错。在那之前,它甚至更加详细地说明了细节。 - Grant Thomas

5

如果我在释放之前没有添加sqlConnection.Close(),这样做会有错吗?

不会有问题,只要你在Using范围内使用连接。当你离开Using范围时,将为SQL连接调用Dispose,这将关闭现有连接并释放所有资源。


4
使用语句是一个try finally块,在您的情况下,最终块将有一个connection.Dispose()调用。因此,您不需要在那里使用独立的connection.Close()语句。
优点是即使出现异常,也可以确保处理,因为finally块始终会运行。
try
{
sqlConnection.Open();
// ....
}
finally
{
if(sqlConnection != null)
      sqlConnection.Dispose();
}

3
不,这是正确的。sqlConnection会在通过using块并调用Dispose方法后关闭连接。SqlConnection.Dispose()等同于SqlConnection.Close()方法。
来自MSDN:如果SqlConnection超出范围,则不会关闭它。因此,您必须通过调用Close或Dispose显式关闭连接。Close和Dispose在功能上是相等的。

3

你正在使用一个Using语句,它将为你Dispose()对象。

如果你将连接放到Using语句之外,那么是的 - 当完成后你需要关闭连接。


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