views:

2081

answers:

6

Can I use this approach efficiently?

using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString))
{
    cmd.Connection.Open();
    // set up parameters and CommandType to StoredProcedure etc. etc.
    cmd.ExecuteNonQuery();
}

My concern is : Will the Dispose method of the SqlCommand (which is called when exiting the using block) close the underlying SqlConnection object or not?

A: 

@huseyint : are you sure of this? There is a connection pool to help exactly this issue but this does not address my problem..

Andrei Rinea
Yes there is a connection pool but everything has its limits. Why do you want to create unnecessary SqlConnection objects instead of creating one and use it with several SqlCommand object?
huseyint
A: 

@lassevk : This is not necessarily true. A closed connection can be reopened. A disposed connection cannot be reopened.

Andrei Rinea
That might be true, but I did answer his question.Disposing of the command object will not dispose of or close the underlying connection.
Lasse V. Karlsen
+15  A: 

No, Disposing of the Command will not effect the Connection. A better approach would be to also wrap the SqlCommand in a using block as well

using (SqlConnection conn = new SqlConnection(connstring))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand(cmdstring, conn))
    {
        cmd.ExecuteNonQuery();
    }
}

Otherwise, the Connection is unchanged by the fact that a Command that was using it was disposed (maybe that is what you want?). But keep in mind, that a Connection should be disposed of as well, and likely more important to dispose of than a command.

EDIT:

I just tested this:

SqlConnection conn = new SqlConnection(connstring);
conn.Open();

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 1", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 2", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

conn.Dispose();

The first command was disposed when the using block was exited. The connection was still open and good for the second command.

So, disposing of the command definitely does not dispose of the connection it was using.

Ryan Farley
You don't need to open the connection before creating the command right? Make it a little cleaner like this:using (SqlConnection conn = new SqlConnection(connstring))using (SqlCommand cmd = new SqlCommand(cmdstring, conn)){ conn.Open(); cmd.ExecuteNonQuery(); conn.Close();}
SkippyFire
I guess the formatting doesn't stick... but basically lump the to using statements together and get rid of a level of nesting. (If you want)
SkippyFire
The point of the example is not to show a simpler syntax, but to demonstrate that both SqlCommands can be used with the same connection and then disposed without disposing of the connection. The connection needs to be opened and then used twice in order to demonstrate this (see original question).
Ryan Farley
A: 

Yes, I've often seen the pattern of nesting two using blocks (the outer for the connection and the inner for the command; or even 3 having the inner-most for the SqlDataReader) but I thought things can be compressed a bit.

Maybe they can't.

Andrei Rinea
A: 

After some thought I have come to the conclusion that a compression of code can still be made like this :

using(SqlConnection con = new SqlConnection("connection string"), SqlCommand cmd = new SqlCommand ("GetSomething", con))
{
  con.Open();
  cmd.ExecuteNonQuery();
}
Andrei Rinea
+3  A: 

SqlCommand.Dispose will not be sufficient because many SqlCommand(s) can (re)use the same SqlConnection. Center your focus on the SqlConnection.