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.
Related
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).
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(...))
{
...
}
I have an application that fires a mysql command (query) "show databases", the query works and returns properly but I can't close my connections. The user I used had 24 connections allowed at the same time so the problem popped up further down my program but reducing the allowed connections to 2 shows me that I can't even close the first query (which isn't in a loop). The code is the following:
protected override Dictionary<string, Jerow_class_generator.Database> loadDatabases()
{
MySqlConnection sqlCon = new MySqlConnection(this.ConnectionString);
sqlCon.Open();
MySqlCommand sqlCom = new MySqlCommand();
sqlCom.Connection = sqlCon;
sqlCom.CommandType = CommandType.Text;
sqlCom.CommandText = "show databases;";
MySqlDataReader sqlDR;
sqlDR = sqlCom.ExecuteReader();
Dictionary<string, Jerow_class_generator.Database> databases = new Dictionary<string, Jerow_class_generator.Database>();
string[] systemDatabases = new string[] { "information_schema", "mysql" };
while (sqlDR.Read())
{
string dbName = sqlDR.GetString(0);
if (!systemDatabases.Contains(dbName))
{
databases.Add(sqlDR.GetString(0), new MySQL.Database(dbName, this));
}
}
sqlCom.Dispose();
sqlDR.Close();
sqlCon.Close();
sqlCon.Dispose();
return databases;
}
P.S. The 'New MySQL.Database(dbName, this));' is my owm made class which only stores the DB structure, could be considered irrelevant.
The exact error I get is 'max_user_connections'. on the connection.open line of the next time a query needs to be fired.
Rather than keeping track of all the Open/Close/Dispose calls all over the place, I'd recommend just replacing all of those with using statements. This will make sure the expected scope of each object is clear and that it will be destroyed/disposed upon exiting that scope.
Close() nor using will help alone with your problem because ADO.NET is using its own connection pooling and connections are by default not closed until program is closed. There are few options to solve this, but consider performance implications and is this really desired behavior for your application.
Add ";Pooling=False" to your connection string.
SqlConnection.ClearPool Method
SqlConnection.ClearAllPools Method
For more information read: SQL Server Connection Pooling (ADO.NET)
Along with the using suggestions above, when creating your sqlDR variable you should use the CloseConnection command behavior to close the actual connection if that is your intended action. As noted in the documentation here.
When the command is executed, the associated Connection object is closed when the associated DataReader object is closed.
So your code to instantiate your reader would look like this:
//to instantiate your variable
MySqlDataReader sqlDR;
sqlDR = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
//closing your datareader reference here will close the connection as well
sqlDR.Close();
If you wrap all your code in a using block using the above method, you don't need any of those Close() or Dispose() methods other than the sqlDR.Close();
when use "using" key word what happen is.when the garbage collector activate it first dispose objects which was declred in using statement.
I recommend using connection pooling in combination with the MySqlHelper class, passing the connection string as the first argument. That allows MySQL to open the connection if necessary, or keep it open according to the pooling cfg, without you having to know about it.
I changed my code to use 1 connection and keep it open and when testing I came across an error that a datareader should be closed. Now since all my queries didn't close the dataReader object (I used dataTable.Load(cmd.ExecuteReader()).) I think the problem might be there.
Keeping 1 open connection worked perfectly so I don't know what caused the not closing problem. I gues it was the dataReader not closing by itself.
Close() will definitely help you close your.
using (MySqlConnection conn = GetConnection())
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "UserDetail";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(new Album()
{
Id = Convert.ToInt32(reader["UId"]),
Name = reader["FirstName"].ToString(),
ArtistName = reader["LastName"].ToString()
});
}
}
}
}
In the above code, you can see one if condition before opening the connection it will help you to reuse your already open connections check below code.
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
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 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