3

当我在如下所示的 using 子句中有 SQLConnection 时,是否需要显式关闭连接?

protected SqlConnection Connection 
{
    get
    {
       if (this.connection == null)
       {
           this.connection = new SqlConnection(this.ConnectionString);
       }
       if (this.connection.State != ConnectionState.Open)
       {
           this.connection.Open();
       }

       return this.connection;
    }
} 

using (SqlConnection connection = this.Connection)
{
    using (SqlCommand cmd = connection.CreateCommand())
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "....";

        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                etc
            }
        }
    }
}
4

3 回答 3

3

using块将始终调用Dispose,这将关闭连接。

但是,您保留了连接对象并打算重用它,这在它被释放后是不可能的。你不应该保留连接对象,你应该把它扔掉并在需要时创建一个新对象。与数据库的实际连接是池化的,因此当您创建一个新的连接对象时,它将重用池中的一个连接。当您释放连接对象时,实际连接将返回到池中。

于 2012-06-21T09:33:40.917 回答
3

不,你没有。如果连接已经打开,则连接的 Dispose() 方法将调用 Close。

您还应该按照 John Gathogo 的建议更改您的代码,以便在每次需要时创建一个新的连接对象。您的代码将失败,因为您第二次尝试使用连接时它已经被释放。

ADO.NET 使用连接池来保持一个打开的连接池,它提供给调用 Open 的任何人。这意味着只要池中有可用的连接,创建和打开新连接就不会花费任何成本。保持连接打开的时间超过必要的时间会降低性能。

于 2012-06-21T09:18:22.197 回答
1

您可以轻松地将代码更改为以下并实现您想要的:

   using (SqlConnection connection = new SqlConnection(this.ConnectionString))
   {
      connection.Open();
      using (SqlCommand cmd = connection.CreateCommand())
      {
         cmd.CommandType = CommandType.StoredProcedure;
         cmd.CommandText = "....";

         using (SqlDataReader reader = cmd.ExecuteReader())
         {
            while (reader.Read())
            {
               //etc
            }
         }
      }
   }

运行时将负责关闭连接并为您处理资源

于 2012-06-21T09:21:13.437 回答