Sql server 处理Sql连接

Sql server 处理Sql连接,sql-server,ado.net,Sql Server,Ado.net,只是想知道,当这个方法完成时,SqlConnection会被关闭吗?还是必须在最后显式调用close方法 using (SqlCommand cmd = new SqlCommand(sql, GetConnection())) { SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { } } SqlConnection GetConnet

只是想知道,当这个方法完成时,SqlConnection会被关闭吗?还是必须在最后显式调用close方法

   using (SqlCommand cmd = new SqlCommand(sql, GetConnection()))
   {
       SqlDataReader reader = cmd.ExecuteReader();
       while (reader.Read())
       {
       }
   }

SqlConnection GetConnetion()
{
 return new SqlConnection("connectionstring");
}
我知道我可以做这样的事情:

SqlConnection conn = GetConnetion();
SqlCommand cmd =new SqlCommand(sql, conn);
//Do Something
conn.Close()
cmd.Dispose()
但我只是好奇在这种情况下,using块将如何工作。
干杯

使用声明将为您解决此问题

否,在您的示例中,连接对象不会自动释放。
using
块仅适用于
SqlCommand
对象,而不适用于连接

要确保释放连接,请确保使用块将
SqlConnection
对象包装在其自己的
中:

using (SqlConnection conn = GetConnection())
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
    // don't forget to actually open the connection before using it
    conn.Open();
    using (SqlDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            // do something
        }
    }
}

哎呀。您希望在连接上使用,而不是在命令上使用。

使用
using
但在连接上使用,而不是在SqlCommand上使用。连接上的Dispose方法将关闭连接(如果启用了池,则将其返回到池)。在SqlDataReader周围也放置一个using:

using(SqlConnection conn = GetConnection())
{
  SqlCommand cmd = new SqlCommand(sql, conn);
  using (SqlDataReader reader = cmd.ExecuteReader())
  {
    do 
    {
      while (reader.Read())
      {
      }
    } while (reader.NextResult());
  } 
}

这有助于你理解正在发生的事情。

卢克的回答是正确的,就你特别询问的关于处理连接的问题而言

为了完整性,您还可以使用该方法而不是无参数方法,传入:

这意味着当
SqlDataReader
关闭时(当它在using构造中被释放时),它将依次关闭它正在使用的连接


但我不喜欢这种方法,因为有一些隐含的逻辑,不清楚到底是什么在关闭连接。

连接没有using语句。发生这种情况是因为在SqlCommand上调用Dipose方法的一部分,还是using语句知道在SqlConnection上调用Close方法?@Dove-请仔细查看。否,“使用”仅适用于该命令。虽然命令包装了对连接的调用,但它不会显式地处理它。由于没有更多的连接引用,GC最终会清理它,但不会像正确处理一样快。哦,我没有仔细阅读。我可能会被纠正,但是连接不会被释放,因为它是在using语句中创建的,或者它必须是那里的主要对象吗?实际上,
SqlConnection
SqlCommand
implement
IDisposable
,所以两者都应该被释放。Fredrik:SqlCommand只是继承了组件Dispose。由于SqlCommand本身没有资源,因此不显式调用Dispose的唯一效果是GC将在第二次传递中收集它,而不是第一次:。我从不费心处理它们(一个坏习惯)。你是对的,实际上围绕着它们包装一个using是一个好习惯,它们可能在未来的版本中有资源要处理,并且是一个好习惯,在using中包装所有IDisposable。我知道
SqlCommand.dispose的内部工作原理;我只是不喜欢我的代码依赖于其他类型的内部(和私有)实现细节(出于您在评论中给出的原因)。+1-正确答案,还要注意stacked using语句的良好使用,而不仅仅是嵌套它们=>更干净的代码。@adrian:我打算在我的回答中提到这种方法,虽然我也不喜欢。此外,您仍然需要确保连接对象在所有情况下都被正确处理:例如,您可以在实例化连接之后但在实例化读取器之前遇到异常。是。我个人不喜欢这种方法,但我认为值得一提。
using (SqlCommand cmd = new SqlCommand(sql, GetConnection()))
{
    using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
        while (reader.Read())
        {}
    }
}