views:

235

answers:

6

Just wondering, Would the SqlConnection be diposed/closed when this method is done? Or do i have to explicitly call the close method at the end?

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

SqlConnection GetConnetion()
{
 return new SqlConnection("connectionstring");
}

I know i can do something like this:

SqlConnection conn = GetConnetion();
SqlCommand cmd =new SqlCommand(sql, conn);
//Do Something
conn.Close()
cmd.Dispose()

But just curious how the using block will work in this case. Cheers

+1  A: 

The using statement will take care of this for you.

dove
+1 Yes, the using statement will do that.
Nick Haslam
There is no using statement for the connection.
Fredrik Mörk
Does this happen because as part of the Dipose method being called on the SqlCommand or does the using statement *know* to call the Close method on the SqlConnection?
@Dove- Look again more carefully.
RichardOD
No, the using only applies to the command. Whilst the command wraps the call to the connection, it doesn't explicitly dispose of it. As there are no more references to the connection the GC will clean it up eventually, but not as quickly as if it was properly disposed.
ck
oh, i had not read that carefully. i may stand corrected, but will the connection not be disposed since it was created in the using statement or must it be the principal object there?
dove
+14  A: 

No, the connection object won't be automatically disposed in your example. The using block only applies to the SqlCommand object, not the connection.

To ensure that the connection is disposed, make sure that the SqlConnection object is wrapped in its own using block:

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
        }
    }
}
LukeH
Yeap- the other answer is incorrect.
RichardOD
+1 - Correct answer, also note the nice use of stacked using statements, instead of just nesting them => cleaner code.
Fredrik Mörk
A: 

Oops. You want to use the using on your connection, not on your command.

Paul Sasik
A: 

Use using but on the connection, not on the SqlCommand. The Dispose method on the connection will close the connection (return it to the pool, if pooling is enabled). Also place an using around the SqlDataReader too:

using(SqlConnection conn = GetConnection())
{
  SqlCommand cmd = new SqlCommand(sql, conn);
  using (SqlDataReader reader = cmd.ExecuteReader())
  {
    do 
    {
      while (reader.Read())
      {
      }
    } while (reader.NextResult());
  } 
}
Remus Rusanu
Actually, both `SqlConnection` and `SqlCommand` implement `IDisposable`, so both should be disposed.
Fredrik Mörk
Fredrik: SqlCommand just inherits the Component Dispose. Since SqlCommand has no resources of its own, the only effect of not calling Dispose explicitly is that the GC will collect it in second pass, not first: http://bit.ly/2WqJeR. I never bother disposing them (a bad habit). You are right, it is a good habit to actually wrap an using around them, they may have resources to dispose in future releases, and is just a good habit to have, wrap *all* IDisposable in using.
Remus Rusanu
I am aware of the inner workings of the `SqlCommand.Dispose`; I just don't like my code to rely on inner (and private) implementation details of other types (for the reasons you give in your comment).
Fredrik Mörk
A: 

Here and Here is something which could help you understanding what is going on.

Greco
Thanks for the links
+2  A: 

Luke's answer is the correct one in terms of what you specifically asked regarding the disposal of the connection.

For completeness, what you could also do is to use the SqlCommand.ExecuteReader(CommandBehaviour) method instead of the parameterless one, passing in CommandBehvaiour.CloseConnection:

using (SqlCommand cmd = new SqlCommand(sql, GetConnection()))
{
    using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
        while (reader.Read())
        {}
    }
}

This signifies that when the SqlDataReader is closed (when it is disposed of in the using construct), it will in turn close the connection that it is using.

I'm not keen on this approach though, as there is some implied logic and it is not obvious what exactly is closing the connection.

adrianbanks
@adrian: I was going to mention this approach in my answer, though I'm not keen on it either. Besides, you still need to ensure that the connection object is properly disposed in all circumstances: For example, you could hit an exception *after* instantiating the connection but *before* instantiating the reader.
LukeH
Yes. I don't like the approach personally, but I thought it was worth mentioning.
adrianbanks