Do we need to close DbCommand in enterprise library 4.1? - c#

My function looks like the below. My question is: do we need to close cmd in this function. My understand is enterprise library automatically closes connection after using.
const String STORED_PROCEDURE_NAME = "LTR_GetLicenseDetails";
const string DB_CONNECTION_NAME = "LTRDB";
MSPData.Database db;
DbCommand cmd = null;
db = CreateDatabase(DB_CONNECTION_NAME);
DataSet ds;
try
{
//Need to close cmd in enterprise libra
cmd = db.GetStoredProcCommand(STORED_PROCEDURE_NAME);
ds = ExecuteDataSet(db, cmd);
}
catch (Exception ex)
{
thrown ex;
}

Database.GetStoredProcCommand returns an IDbCommand which implements IDisposable. In general, if an object implements IDisposable then it should be disposed when the object is no longer needed.
In fact if you call Enterprise Library methods that don't take a command they will construct a command and dispose it. e.g.
public virtual DataSet ExecuteDataSet(string storedProcedureName,
params object[] parameterValues)
{
using (DbCommand command = GetStoredProcCommand(storedProcedureName, parameterValues))
{
return ExecuteDataSet(command);
}
}
Your understanding of Enterprise Library is correct -- the connection will be closed when calling one of the Database.Execute* methods (e.g. ExecuteDataSet). So not disposing the command object will not result in orphaned database connections. However, it may result in some other type of leak depending on the database provider.
In terms of SQL Server, the last time I looked at SqlCommand there was no obvious harm done if the object is not disposed and the only issue I recall seeing was the parameter cache would have to wait until garbage collection to be released.

Related

Database Connection from another class

I have created a class in my program to handle database connection. This class includes a method named OpenConnection() to open the connection to the database. I'm not convinced that my program meets the standard of clean code. Here is the method.
public void OpenConnection()
{
if(connection==null || connection.State != Connection.Open)
{
connection = new OracleConnection(this.connectionString);
connection.Open();
}
}
This method works okay but I just want to make sure if this is a safe way and I am not exploiting my program in any way. Thank You in advance
Update
I also added the following methods in the class to close the connection and dispose it.
public void CloseConnection()
{
if (dbconnect != null | dbconnect.State != ConnectionState.Closed)
{
dbconnect.Close();
}
}
//Here the IDsiposable method is implemented
public void Dispose()
{
CloseConnection();
}
You can use using clause and it's going to handle the Dispose automatically.
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#EmployeeID", 123));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
connection.close();
}
Your solution as coded seems ok if you add the cases suggested in this answer and if it's meant to be used on a single thread and within a very limited scope. That said it appears like you are gearing up to use this class as a parameter across many method calls because you want to
mix business logic and persistence concerns
or share an instance in such a way that other methods don't have to be concerned about whether to open the connection (e.g. a higher call in the call stack has not yet called Open) or not (e.g. a prior call in the call stack did open the connection (what we'd call an "ambient" connection)).
Either of these strategies usually leads to trouble. It's better to keep the scope small, where you know the connection is open and when to close it:
using (var connection = new OracleConnection(...))
{
connection.Open();
...
}
When you have this small scope, your abstraction now provides no value.
You have a possible resource leak owing to the fact that OracleConnection implements IDisposable. Also, calling close on a connection in ConnectionState.Executing or Fetching could be bad as it will rollback all uncommitted transactions.
public void OpenConnection()
{
if (connection == null)
{
connection = new OracleConnection(this.connectionString);
connection.Open();
return;
}
switch (connection.State)
{
case ConnectionState.Closed:
case ConnectionState.Broken:
connection.Close();
connection.Dispose();
connection = new OracleConnection(this.connectionString);
connection.Open();
return;
}
}

Why must I use Dispose()?

Here is my code:
public void InsertData()
{
using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString))
{
using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection))
{
connection.Open();
command.ExecuteNonQuery();
}
}
}
But I found this code sample:
public void InsertData()
{
SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
command.ExecuteNonQuery();
command.Dispose();
connection.Close();
connection.Dispose();
}
why does the author use
command.Dispose()
and
connection.Dispose();
in their code?
using can only be used on objects that are disposable (which is when they implement the interface IDisposable). Doing so will automatically call Dispose on that instance. However in contrast to call it yourself the using-statement ensures that Dispose is also called when an exception whithin that block occurs. So it´s safer to use that approach.
Your first example is equivalent to this:
try
{
SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
try
{
command.ExecuteNonQuery();
}
finally
{
command.Dispose();
}
}
finally
{
connection.Dispose();
}
You'll have resource leak when exception has been thrown:
public void InsertData()
{
SqlConnection connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand("Some Simple Insert Query", connection);
command.ExecuteNonQuery(); // <- imagine that this throws exception
// and so these don't execute at all and you'll have two resources leaked:
// 1. Connection
// 2. Command
command.Dispose();
connection.Close();
connection.Dispose();
}
The reasons of the exception can vary:
1. Insert failed (e.g. invalid field value insertion)
2. User doesn't have privelege required
3. RDMBS Internal error
...
You can emulate using with try .. finally which is wordy:
public void InsertData()
{
SqlConnection connection = null;
try {
connection = new SqlConnection(DBHelper.ConnectionString);
connection.Open();
SqlCommand command = null;
try {
command = new SqlCommand("Some Simple Insert Query", connection);
command.ExecuteNonQuery();
}
finally { // rain or shine, dispose the resource (if it has been created)
if (command != null)
command.Dispose();
}
}
finally { // rain or shine, dispose the resource (if it has been created)
if (connection != null)
connection.Dispose();
}
You don't have to use dispose in your example, because the using block does that for you.
See here: using Statement (C# Reference)
He is using connection.Dispose(); because the person is inexperienced and is writing bad code that is not safe. If a exception is thrown the connection will never be disposed of causing it to remain open till the GC collects the connection maybe minutes or hours later.
The using block is just syntactic sugar for the try/finally Dispose() pattern. This is all explained in the documentation.
Note you can also reduce the indentation in your code:
using (SqlConnection connection = new SqlConnection(DBHelper.ConnectionString))
using (SqlCommand command = new SqlCommand("Some Simple Insert Query", connection))
{
connection.Open();
command.ExecuteNonQuery();
}
In .Net IDisposable and the Dispose method are used to clean up unmanaged resources.
.Net keeps track of managed resources so it can clean them up automatically, but it needs to have some help when dealing with unmanaged resources.
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
https://msdn.microsoft.com/en-us/library/system.idisposable.dispose(v=vs.110).aspx
The using statement is a way to automatically call the Dispose method when you're done using it.
Provides a convenient syntax that ensures the correct use of IDisposable objects.
It'll even get called if an exception is called.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.
https://msdn.microsoft.com/en-us/library/yh598w02.aspx
The code which isn't using the using statements is incorrect.
It'll work most of the time, but if an exception occurs the unmanaged resources in SqlConnection could be left uncleaned.
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement.

When does SqlCommand close when used in another function?

I have a program in C# where I created various class, and all of them need to make calls to the database. So I decided to create a static class that handles all the calls to allow me to apply far-reaching changes very easily. Within that class I have functions that call the various parts of SqlCommand (ExecuteReader(), etc) I finally got tired of rewriting all the connection code, and abstracted it out to another function called getSqlCommand() which just returns an initialized SqlCommand which I use to perform the various commands. I've chosen to not pass the SqlCommand back to the other programs (though it is a public method in case I need it) because there is some pre-processing if you will that I may do before I had the results back to the program.
My question is, if/when the SqlConnection closes? Since it is being passed back as a return value in a SqlCommand, will it be left open? and if so, can I close it? Here is some code (slightly stripped down) so you can see what I am doing, thanks in advance!
The function to create the SqlCommand:
public static SqlCommand GetSqlCommand(string query)
{
using (SqlConnection dbConnection = new SqlConnection( SQLConn )) {
dbConnection.Open();
SqlCommand cmd = new SqlCommand( query, dbConnection );
cmd.CommandTimeout = 0;
return cmd;
}
}
An example of the usage of the command in the static class:
public static SqlDataReader executeReader( string query )
{
try {
return GetSqlCommand(query).ExecuteReader();
} catch (SqlException) {
//Notify User and Resolve Error
}
return null;
}
A SqlConnection is closed when you call Dispose. Exiting the using block does that. The connection will be closed.
That's all there is to it. It will not magically stay open because ADO.NET does not know and cannot find out that you returned the connection object.
Move the connection out of the GetSqlCommand method. Pass the connection object into that method. GetSqlCommand has no business in creating a connection. It should take a connection, use it, but not close it.
The connection closes before the code exits the GetSqlCommand method. That means that the command object that it returns is useless.
The using construct creates a try ... finally block, where it disposes the connection at the end of the block. As disposing the connection also closes it, the connection is already closed before the command object is returned from the method to the caller.
The using keyword is equivalent to use try finally, and within the finally block your connexion will be disposed
SqlConnection dbConnection = new SqlConnection( SQLConn );
try
{
dbConnection.Open();
SqlCommand cmd = new SqlCommand( query, dbConnection );
cmd.CommandTimeout = 0;
return cmd;
}
catch(Exception ex)
{
}
finally
{
dbConnection.Dispose();
}
And even if there is a return statement inside a try block , the block finally will always be executed

disposing multiple objects that reference each other in c#

Okay, I've searched "similar" topics but still haven't come across any answer to what I'm going to ask here.
I have a function that creates multiple sql objects under the System.Data.SqlClient namespace. I've read that the using statement disposes of an object after the using block but the variables declared are readonly. My function reuses some of these variables, so I can't really declare them within a using statement.
Here is the body of my function for clarity. Should I call Dispose on the other objects (command, transaction, reader, etc) or will using recursively dispose of them through the connection object? How should I dispose these objects?
I'm still new to C# (I come from C/C++ background) so please forgive me if the question sounds very ignorant.
public string SignIn(string userId, string password)
{
SqlCommand sqlCommand = null;
SqlTransaction sqlTransaction = null;
string sessionId = "";
using(SqlConnection sqlConnection = new SqlConnection Properties.Settings.Default.SessionManagerDBConnectionString))
{
try
{
sqlConnection.Open();
sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "GetUserByUserIdPassword";
sqlCommand.CommandTimeout = 30;
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterUserId = sqlCommand.Parameters.Add("#UserId", SqlDbType.NVarChar, 32);
parameterUserId.Value = userId;
SqlParameter parameterPassword = sqlCommand.Parameters.Add("#Password", SqlDbType.NChar, 64);
parameterPassword.Value = this.GetSHA256Hash(password);
sqlTransaction = sqlConnection.BeginTransaction("SampleTransaction");
// more database activity, execute command, store results in datareader
sqlTransaction.Commit();
sqlConnection.Close();
}
catch (SqlException ex)
{
if(sqlTransaction != null)
sqlTransaction.Rollback();
MessageBox.Show(ex.Number + ":" + ex.Message, ex.Server + ":" + ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return sessionId;
}
I tried to search for similar questions again and found some closer answers.
Is SqlCommand.Dispose() required if associated SqlConnection will be disposed?
Does SqlCommand.Dispose close the connection?
I suppose I should add a finally clause to my try-catch and call several Dispose methods there for all the sql objects I've created. I hope that suffices or is there a recommended style of doing this?
finally
{
if(sqlCommand != null)
sqlCommand.Dispose();
if(sqlTransaction != null)
sqlTransaction.Dispose();
...
}
I tried putting a using statement within the try-catch block for one of the sqlCommand objects, but if that part of the code aborts when an exception is thrown, the execution jumps down to the catch portion. The using does not dispose that sqlCommand object.
try
{
...
using(sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = "GetUserByUserIdPassword2";
sqlCommand.CommandTimeout = 30;
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterUserId = sqlCommand.Parameters.Add("#UserId", SqlDbType.NVarChar, 32);
parameterUserId.Value = userId;
SqlParameter parameterPassword = sqlCommand.Parameters.Add("#Password", SqlDbType.NChar, 64);
parameterPassword.Value = this.GetSHA256Hash(password);
SqlDataReader reader = sqlCommand.ExecuteReader(CommandBehavior.SingleRow);
// throws exception, no stored procedure "GetUserByUserIdPassword2"
}
...
}
catch() {}
// sqlCommand still accessible at this point because using above was "aborted".
If the object implements IDisposable, then use using. If you need to create a new SqlCommand for some reason then finish one using block and start a new one. Or nest them if you still need access to the first SqlCommand.
You can reuse SqlCommand objects, as long as you haven't got a datareader still open from the command. So, you could create a SqlCommand, set all its properties and execute it, then reset all its properties and execute it again and so on. This does save slightly on the costs of memory allocation, but I think it also reduces the clarity of the code, so it is something I would only do if profiling proved it necessary.
will using recursively dispose of them through the connection object
Of course, using knows nothing about SqlConnections or other ADO.NET objects. All it knows is to call Dispose. Whatever the object being disposed does is what happens.
It happens to be the case that disposing a SqlConnection also disposes of the resources of all readers and commands associated with the connection. You only need to dispose the connection.
I don't know whether this is documented on MSDN but I know it from decompiling the assemblies. For compatibility reasons they can never change this behavior so it is safe to rely on it.
In general, you must call dispose on any object implementing IDisposable. Exception to this rule is when you know for sure that it is safe to not call Dispose. Like in this case.
I think I found the answer!
Even though the sqlCommand object was still accessible in the bottom parts of the code when a nested using statement was skipped by a thrown exception, sqlCommand is still disposed later on. I tested this by actually assigning a function to the disposed event of said sqlCommand object.
The code here is slightly different than above because of the transaction object requirement. But the logic is essentially the same.
try
{
using(sqlCommand = new SqlCommand("GetUserByUserIdPassword2", sqlConnection, sqlTransaction))
{
sqlCommand.CommandTimeout = 15;
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterUserId = sqlCommand.Parameters.Add("#UserId", SqlDbType.NVarChar, 32);
parameterUserId.Value = userId;
SqlParameter parameterPassword = sqlCommand.Parameters.Add("#Password", SqlDbType.NChar, 64);
parameterPassword.Value = this.GetSHA256Hash(password);
sqlCommand.Disposed += new System.EventHandler(this.sqlCommand_Disposed);
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.SingleRow);
// exception thrown, no sored proc "GetUserByUserIdPassword2"
sqlDataReader.Close();
}
}
catch(...) {}
...
private void sqlCommand_Disposed(object sender, EventArgs e)
{
MessageBox.Show("sqlCommand has been disposed");
}
So, basically, even if a nested using statement is "aborted" by a thrown exception within the try block, and execution is skipped down to the catch block, the Dispose method is still called for that object after the function exits (or when the variable goes out of scope).
I presume this behavior is the same for any number of nested using statements.
in CSharp, using is a special keyword which have different acts in code..
if you put using to top of the codepage then using acts as c++ ' s Include or VB (and some other script langs') Import
if you write a "using" which follows by a paranthesis then it acts like an alias of Dispose() method of CSharp.. or Destructor tilda of c++ or free() method of plain c..
About SQL Connection.. Best way is first Close() the connection (so with this, connection is still alive -actually just ready to use- but null.. return to wait new order in connection pool.. ) and then dispose if you need..
if you have still problems and suspected that calling the Dispose() method not enough to free the resources
then you can use Garbage Collector's Collect() static method to force the garbage collection
But not so much recommended by Microsoft because of face with accidental garbage collection problems (i.e. you collect the form but need some variable from that form )
in example of usage :
public void Dispose (bool ForceToCollect )
{
if (ForceToCollect)
GC.Collect (0, GCCollectionMode.Forced );
}
In Gc.Collect() method you can set which group of data memory freed with first option where is int..if you plan to free resources of the last group - means last created group of items, as an example last created form instance and its all child controls - then int should be 0; the one which is 1 before the last created then should be 1 and so on..
Hope this helps..

SqlServer Class static methods - Thread Safety

I have created a class to ease the use of SQL server within my app.
public static class SqlServer
{
public static void QueryNoReturn(string ConnectionString, string Query, SqlParameter[] Parameters, bool IsStoredProcedure)
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
// Create the command to run
SqlCommand command = new SqlCommand(Query, conn);
// If we are running a stored procedure
if (IsStoredProcedure)
command.CommandType = System.Data.CommandType.StoredProcedure;
// Add parameters if they exist
if (Parameters != null)
command.Parameters.AddRange(Parameters);
try
{
// Open the connection to the database
conn.Open();
// Execute the command and assign to the result object
command.ExecuteNonQuery();
conn.Close();
command.Parameters.Clear();
}
catch (SqlException sqlex)
{
throw new Exception(
string.Format("{0} \"{1}\"", IsStoredProcedure ? "Procedure" : "Query", Query),
sqlex);
}
}
}
}
If I am calling this static method many times a second (approx. 50) then will I see issues with thread safety?
I could easily create a Factory or some other instance specific object, but I went with this option out of simplicity.
Since you are not using any shared resources of the class, this appears to be "thread-safe".
This of course disregards any concurrency issues on the database itself.
You should wrap the SqlCommand creation in a using statements as well.
Since you are creating the SqlConnection in a using statement, you don't need to explicitly call Close on it, as it will be done when the connection is disposed.
No. You could get into thread safety problems when you access shared resources, but you don't do that (at least not in this method).
By the way, move the conn.Close(); to a finally clause, that way the connection is closed, even when you get an exception.

Categories