I have been trying to search for this and could not find an answer, May be I was not looking at the right places so please bear with me...
Question:
I know that a using statement calls the dispose method of the object, for example:
using (SqlConnection conn = new SqlConnection(conString))
{
// some work
}
// dispose method for this connection object will be called must.
But what happens to the objects created inside this using statement?
using (SqlConnection conn = new SqlConnection(conString))
{
SqlCommand cmd = new SqlCommand(query, conn);
// some work
}
Will the dispose method of command object be also called? Or should I do this instead:
using (SqlConnection conn = new SqlConnection(conString))
{
using (SqlCommand cmd = new SqlCommand(query, conn))
{
//some work
}
// some work
}
Which is the best practice and which one will be more efficient ?
Will the dispose method of command object be also called?
No
Or should I do this instead:
Yes
Which is the best practice and which one will be more efficient ?
The one that works - the last one. Note you can avoid "heading right" on the page:
using (SqlConnection conn = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
// some work
}
I'm too lazy to use ADO.NET directly; another option is to get a tool to handle everything except the connection (example shown is "dapper", but other tools exist):
using (SqlConnection conn = new SqlConnection(conString))
{
var data = conn.Query<SomeType>(someSql, new { foo, bar }).ToList();
// where #foo and #bar are parameters in the sql
}
then you don't need to worry about the command, data-reader, parameters, etc.
Yes you should use the second. also you can shorten that statement to:
using (SqlConnection conn = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
//some work
}
// some work
If you don't wrap your disposable object with a using statement the Dispose method will not be called.In your case only the connection will be disposed.
I know that a using statement calls the dispose method of the object, for example:
If that object implements the IDisposable interface. Otherwise, you can't even use an object in a using statement.
You should use a using statement for each object you want to dispose of after some operations. So you should use the last example you provided yourself (with the two using statements).
Related
This question already has answers here:
Is SqlCommand.Dispose() required if associated SqlConnection will be disposed?
(6 answers)
Closed 6 years ago.
I've doubt what is the significant difference by applying the "Using" statement in same code block with different way , it would be good to know practice the best way for me
sameple 1 code block
using (SqlConnection SqlConnection = new SqlConnection(dbConnectionString))
{
SqlConnection.Open();
using (var command = new SqlCommand(store_procName, SqlConnection))
{
command.Parameters.Add(Constants.PARAM_Value, SqlDbType.VarChar).Value = Id;
command.CommandType = CommandType.StoredProcedure;
using (var adp = new SqlDataAdapter(command))
{
adp.Fill(dtValid);
}
}
}
return dtValid;
sample code block 2
using (SqlConnection SqlConnection = new SqlConnection(dbConnectionString))
{
SqlConnection.Open();
SqlCommand command = new SqlCommand(store_procName, SqlConnection);
command.Parameters.Add(Constants.PARAM_Value, SqlDbType.VarChar).Value = Id;
command.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adp = new SqlDataAdapter(command);
adp.Fill(dtValid);
}
return dtValid;
The using statement is syntactical sugar to release resources (eg memory or handles) without having to write the code for that yourself. So a code snippet like
using (var adp = new SqlDataAdapter(command))
{
adp.Fill(dtValid);
}
is converted into something like:
SqlAdapter adp = null;
try
{
adp = new SqlDataAdapter(command);
adp.Fill(dtValid);
}
finally
{
if (adp != null) adp.Dispose();
// or rather (adp as IDisposable)?.Dispose();
}
(this is just an example to give you the idea, not necessarily the exact code generated by the compiler).
So if you ommit the inner using statements in your code, the Dispose() methods of the instances will not be called at this point. Eventually the garbage collection will clean up those objects (which normally leads to calls to Dispose()).
The difference is relevant if you have a lot of calls to this method and read a lot of data so that the SqlCommand and the SqlDataAdapter will consume a lot of resources. If you want to release these resources as soon as possible, you should include the code in using statements.
You are asking for the best practice (which is often a matter of taste). In most cases the first snippet (with all the using statements) is preferable, because it releases all resources that are no longer needed immediatly.
I have the following set of code:
using (OracleConnection conn = new OracleConnection(m_fceConn))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
{
using (OracleDataReader reader = cmd.ExecuteReader())
{
reader.Read();
}
}
conn.Close();
}
Is there a better way to format this? Granted, later on I will probably be breaking out opening a connection, running a query, and closing the connection into separate functions at a later date but this nesting will still be there "behind the scenes" so to speak.
I read on another thread that I could format things like so:
using (OracleConnection conn = new OracleConnection(m_fceConn))
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
But considering that I have code in between each of these statements I don't believe that I can omit the brackets like that. I'm just looking for the best/safest practice here since I'm still realtively new/noob to C#. Thanks.
I could be wrong, but I don't think you need to open the connection before passing it to OracleCommand. You just have to open it prior to executing a command. So you could write the above as:
using (OracleConnection conn = new OracleConnection(m_fceConn))
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
{
conn.Open();
using (OracleDataReader reader = cmd.ExecuteReader())
{
reader.Read();
}
}
(you also shouldn't need to explicitly close either since disposing of the connection should close it automatically).
There's nothing special about the above code (other than it looks nice), it's just using normal C# rules that apply single commands to such blocks. it's the same as this:
if (...)
if (...)
dosomething(); // Look Ma, no curly braces
it's just that you're "stacking" multiple single statements.
What you have is properly formatted, though it's not necessary to call conn.Close() since the connection will be disposed (and thus closed) at the end of the using block that declared it.
You can, however, omit the brackets for the second statement, since the entirety of that statement is just another using block.
Your first using statement needs to have brackets, since you have the conn.Open() call there. The second and third can be stacked as you stated, which is pretty idiomatic C# (and preferred, in my case).
using (OracleConnection conn = new OracleConnection(m_fceConn))
{
conn.Open();
using (OracleDataReader reader = new OracleCommand(m_sql, conn).ExecuteReader())
{
reader.Read();
}
conn.Close();
}
EDIT
On second thought, don't do this. It wouldn't dispose of the command object. I will leave the answer here as an example of what NOT to do.
I have the code below:
using (SqlCommand command = new SqlCommand())
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Connection = new SqlConnection();
command.CommandText = "";
command.Parameters.Add(new SqlParameter("#ExperienceLevel", 3).Direction = System.Data.ParameterDirection.Input);
SqlDataReader dataReader = command.ExecuteReader();
}
Is there any functional impact in declaring the SqlConnection where I currently am declaring it as opposed to like so?:
using (SqlCommand command = new SqlCommand())
using (SqlConnection connection = new SqlConnection())
Thanks
Yes, there's a difference. Disposing the SqlCommand does not automatically dispose the SqlConnection it's associated with. You can leak connections that way, and it will interfere with ADO.NET connection pooling; if you take a look at the database server's activity while this code runs, you'll see new connections being opened and not closed.
You should always be using the second version. In fact, the SqlConnection object is the one that you really need to Dispose. You should always dispose anything that implements IDisposable as soon as possible, but failing to dispose a SqlConnection is particularly dangerous.
Yes, preferably use 2 using blocks, 1 per resource.
In this case you could use just 1 but it should be around the Connection, not around the Command.
But you really don't want to know or care about such details. If a class implements the IDispsoable interface then use its instances in a using() { } block unless there is a special reason not to.
I use the following pattern:
using(var connection = new SqlConnection("ConnectionName"))
using(var command = new SqlCommand())
{
command.Connection = connection;
// setup command
var reader = command.ExecuteReader();
// read from the reader
reader.Close();
}
Yes, the below code will dispose the SqlConnection correctly, the above won't. A using block (implemented internally as try...finally) ensures that the object will be disposed no matter how you exit the block.
i took this code from msdn
string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
}
}
as you can see there is no using for the SqlCommand here, so, does it needs to be ?
You need a using for every object you create that implements IDisposable. That includes the SqlCommand and the SqlConnection.
There are very few exceptions to this rule. The main exception is WCF client proxies. Due to a design flaw, their Dispose method can sometimes throw an exception. If you used the proxy in a using statement, this second exception would cause you to lose the original exception.
You don't NEED to use a using statement, but it is good practice and you SHOULD use it. It allows objects using IDisposable to be disposed of automatically.
http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx
Edited to add link and remove inaccurate statement because #John Saunders is right.
I have two questions.
1) Should you always use a using statement on a connection? So, I would use it on the connection and then another one on a reader within the connection? So I would be using two using statements.
2) Lets say you use the using statement on the connection and also a reader being returned on the connection. So you have two using statements. Does it create two Try{}Finally{} blocks or just one?
Thanks!
Be careful here. You should always have a using statement on any local object that implements IDisposable. That includes not only connections and readers, but also the command. But it can be tricky sometimes exactly where that using statement goes. If you're not careful it can cause problems. For example, in the code that follows the using statement will close your reader before you ever get to use it:
DataReader MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
return rdr;
}
}
}
Instead, you have four options. One is to wait to create the using block until you call the function:
DataReader MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
return cmd.ExecuteReader();
}
}
using (var rdr = MyQuery())
{
while (rdr.Read())
{
//...
}
}
Of course, you still have to careful with your connection there and it means remember to write a using block everywhere you use the function.
Option two is just process the query results in the method itself, but that breaks separation of your data layer from the rest of the program. A third option is for your MyQuery() function to accept an argument of type Action that you can call inside the while (rdr.Read()) loop, but that's just awkward.
I generally prefer option four: turn the data reader into an IEnumerable, like this:
IEnumerable<IDataRecord> MyQuery()
{
string sql="some query";
using (var cn = new SqlConnection("connection string"))
using (var cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
yield return rdr;
}
}
}
Now everything will be closed correctly, and the code that handles it is all in one place. You also get a nice bonus: your query results will work well with any of the linq operators.
Finally, something new I'm playing with for the next time I get to build a completely new project that combines the IEnumerable with passing in a delegate argument:
//part of the data layer
private static IEnumerable<IDataRecord> Retrieve(string sql, Action<SqlParameterCollection> addParameters)
{
//DL.ConnectionString is a private static property in the data layer
// depending on the project needs, it can be implementing to read from a config file or elsewhere
using (var cn = new SqlConnection(DL.ConnectionString))
using (var cmd = new SqlCommand(sql, cn))
{
addParameters(cmd.Parameters);
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
yield return rdr;
}
}
}
And then I'll use it within the data layer like this:
public IEnumerable<IDataRecord> GetFooChildrenByParentID(int ParentID)
{
//I could easily use a stored procedure name instead, and provide overloads for commandtypes.
return Retrieve(
"SELECT c.*
FROM [ParentTable] p
INNER JOIN [ChildTable] c ON c.ParentID = f.ID
WHERE f.ID= #ParentID", p =>
{
p.Add("#ParentID", SqlDbType.Int).Value = ParentID;
}
);
}
1) Should you always use a using
statement on a connection? So, I would
use it on the connection and then
another one on a reader within the
connection? So I would be using two
using statements.
Yes, because they implement IDisposable. And don't forget a using statement on the command too :
using (DbConnection connection = GetConnection())
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT FOO, BAR FROM BAZ";
connection.Open();
using (DbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
....
}
}
}
2) Lets say you use the using
statement on the connection and also a
reader being returned on the
connection. So you have two using
statements. Does it create two
Try{}Finally{} blocks or just one?
Each using statement will create its own try/finally block
You should always use a using statement when an object implements IDisposable. This includes connections.
It will create two nested try{}finally{} blocks.
Special point on 1). You need to specifically avoid that technique when the connection is used in asynchronous ADO.NET methods - like BeginExecuteReader, because more than likely, you will fall out of scope and try to dispose the connection while the async operation is still in progress. This is similar to the case when you are using class variables and not local variables. Often times the connection reference is stored in a class used as the "control block" for the asynchronous operation.
To answer each one:
1) Yes, this would be best practice to dispose both as soon as possible.
2) using() will create two blocks, wrapped in each other in the same order. It will dispose the inner object (the reader) first, then dispose the object from the outer using (the connection).
Probably this article will be interesting for you: How to Implement IDisposable and Finalizers: 3 Easy Rules