Should I use several nested "using" stements? - c#

I'm wondering whether I should use using statement inside another?
For example:
using(SqlConnection con = new SqlConnection(...))
{
...
using(SqlCommand cmd = new SqlCommand(...))
{
}
...
}
Are both "usings" necessary or would the first using dispose of everything when it's done?

You need to use a using statement for each object you want to dispose.
I think that you will better understand this if you know that a using statement is mostly syntactic sugar, under the hood something like this is generated:
myObject m = new myObjecyt()
try
{
// Code here
}
finally
{
m.Dispose();
}
It might be desirable in your present context to dispose of every object contained within a single using block but in many other contexts, this behavior is not desirable.

You need both because they are completely independent, each one disposes its own variable. If you have multiple consecutive using statements you can also write them like this
using(SqlConnection con = new SqlConnection(...))
using(SqlCommand cmd = new SqlCommand(...))
{
...
}

Related

SqlConnection.BeginTransaction(IsolationLevel.ReadUncommitted).Commit();

Folks I ran into a bit of code and I'm a tad confused about whats going on.
I'm working to refactor the code to instead process a handful of SqlCommands rather than the single SqlCommand that it currently works with. It's my hope all SqlCommands can be processed under ONE transaction.
Each SqlCommand is a Stored Procedure, so in effect my transaction would call one (or many) Stored Procedures - first off, is that even possible?
Regardless, here's the code block:
public virtual void Execute()
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
SqlCommand storedProcedure = new SqlCommand(BlahBah, conn);
storedProcedure.CommandType = CommandType.StoredProcedure;
conn.Open();
**conn.BeginTransaction(IsolationLevel.ReadUncommitted).Commit();**
storedProcedure.ExecuteNonQuery();
conn.Close();
}
}
In particular the highlighted statement that sets a Transaction on the Connection object, appended with a ".Commit()".
The actual source code has no ROLLBACK, nor anywhere is there a COMMIT. Am I essentially seeing some sort of AutoCommit? Does it even make sense to have a TRANSACTION here if for example the DB doesn't require TRANSACTIONal processing?
Perhaps more important to my refactoring efforts, would something like this make sense? That's to ask, if I processed 10 Stored Procedures and the last one threw an error, would there be an auto ROLLBACK on all 10?
Here's where I want to land:
public virtual void ExecuteTest()
{
using (SqlConnection conn = new SqlConnection(ApplicationConfig.DbConnectInfo.ConnectionString))
{
var errorText = string.Empty;
conn.Open();
conn.BeginTransaction(IsolationLevel.ReadUncommitted).Commit();
foreach (var storedProcedure in StoredProcedures)
{
storedProcedure.Connection = conn;
storedProcedure.ExecuteNonQuery();
}
conn.Close();
}
}
EDIT: this MS link suggests the approach will work:
SqlConnection.BeginTransaction Method (IsolationLevel)
Thank you for your interest.

What happens to the objects created inside a using statement?

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).

Proper format of nested "using" statements?

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.

Difference in declaring IDisposable member in using block or at using block declaration?

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.

Using statement question

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

Categories

Resources