【问题标题】:Does a SQL connection close with "using" if the connection comes from a static class?如果连接来自静态类,SQL 连接是否会以“使用”关闭?
【发布时间】:2019-04-16 20:26:52
【问题描述】:

我是否通过将 SQL 连接放置在“使用”块中来正确关闭它?

这就是我获取新连接、执行查询并返回结果的方式:

using (SqlConnection objCS = DB.LMSAdminConn())
{
    objCS.Open();
    SqlCommand objCommand = new SqlCommand("SELECT TOP 1 * FROM users WHERE userid = @userid", objCS);
    objCommand.Parameters.Add("@userid", SqlDbType.Int).Value = userid;
    SqlDataReader reader = objCommand.ExecuteReader();
    while (reader.Read())
    {
        //do something
    }
    reader.Close();
}

连接本身来自这个调用:

public static SqlConnection LMSAdminConn()
{
    return new SqlConnection(ConfigurationManager.ConnectionStrings["lmsadmin"].ToString());
}

我正在“使用”块内打开连接,我认为连接也会关闭,因为它是在“使用”块内打开的。但是由于“新的 SqlConnection”对象实际上是从外部类生成的,我的连接是否仍然被适当地关闭? SQL Server 显示连接仍处于打开状态,但我不确定这是否是 ADO.NET 连接池回收/共享,或者连接是否真正保持打开状态。我没有在“使用”块内的连接上明确调用 .Close()。

我是否还需要显式关闭 SqlCommand 和 SqlDataReader 对象,或者当我们离开“使用”块时它们也被释放?

【问题讨论】:

  • using 语句不知道也不关心对象“来自”什么。它将处置其对象。
  • using 块终止时,它们将被关闭和处置。你可以阅读文档here
  • Using 语句将在上述情况下处理您的连接。
  • 您应该对(几乎)所有实现IDisposable 并且您没有在非局部变量中维护引用的对象使用using 语句。所以是的,把你的SqlCommandSqlDataReaders 也放在那里。

标签: c# asp.net .net sql-server ado.net


【解决方案1】:

using 块本质上是语法糖,因为 try/finally 块调用它所作用对象的 Dispose 方法,无论该对象是在哪里创建的。

对于SqlConnection 对象,调用Dispose 将关闭连接。来自the docs

如果 SqlConnection 超出范围,它不会被关闭。因此,您必须通过调用CloseDispose 显式关闭连接。 Close 和 Dispose 在功能上是等效的。

【讨论】:

    【解决方案2】:

    是的,一旦失去作用域,它将关闭连接。 示例:

    using (SqlConnection sqlConn = new SqlConnection("myConnectionString"))
    {
      sqlConn.Open();
      ...
    }
    

    此代码将被编译器转换为以下代码:

    try
    {
        SqlConnection sqlConn = new SqlConnection("myConnectionString");
        sqlConn.Open();
        ...
    }
    finally
    {
       sqlConn.Close();
    }
    

    如您所见,close()finally 块中被调用。 这个 finally 块将强制关闭连接,即使在 using 块内的运行时出现异常。

    【讨论】:

    • 您的翻译有误。 sqlConn变量的声明和实例化是在try块开始之前完成的,finally子句不会调用Close,它会调用Dispose。正确翻译请参考official documentation
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    相关资源
    最近更新 更多