I'm not sure even if nested SqlConnections
are possible but I would really like to stay away from it. I've run into a scope issue now in my code and I'm trying to figure out how to get around it.
So until recently I had a global SqlConnection
which is opened when the application starts and closed when it finished. I've now discovered the concept of .NET's connection pool so I've changed my code such that every SqlCommand
(or group of them) uses its own, freshly created and opened, SqlConnection
, trusting .NET to manage the pool and the accompanying overhead.
The problem I'm now having is that I have several blocks of code that look something like this:
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand1 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand1.ExecuteNonQuery();
}
using (SqlCommand sqlCommand2 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand2.ExecuteNonQuery();
}
.
.
.
ClassGlobal.WriteAction(action);
}
while the ClassGlobal.WriteAction() function looks something like this:
public static void WriteAction(MyActionClass action)
{
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("Write the action to the DB", sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}
}
As you can see, a new SqlConnection
is created inside WriteAction()
which is called from inside the scope of the first SqlConnection
. Not good! I'm trying to avoid this.
In the past it wouldn't have been a problem seeing as there were none of these using (SqlConnection)
blocks and all SqlCommands
pointed to the same (global) SqlConnection
. Obviously I could simply move my call to WriteAction()
down below the closing curly brace of the using (SqlCommand)
but:
- The
action
instance that I pass to it is often instantiated and populated while inside the scope of the SqlConnection
so I'd have to make more changes (lots of them) to move those out of the SqlConnection
scope. There are loads of them and it will be hairy.
- I'd actually prefer if the
WriteAction()
call could be inside the SqlConnection
scope as in the example above so that I can wrap all of it in a TransactionScope
, something that wasn't possible thus far but certainly seems like a good idea.
So here's what I plan on doing but I'd like to hear if any of you would consider this not to be good practice or whether you can suggest a better approach. (I've recently discovered that my global SqlConnection
was not a good practice and it resulted in lots of time spent on fixing it. I'd like to avoid such a discovery in future).
How about I add a parameter to the WriteAction()
function so that it looks as follows:
public static void WriteAction(MyActionClass action, SqlConnection sqlConnection)
{
using (SqlCommand sqlCommand = new SqlCommand("Write the action to the DB", sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}
This means that, rather than moving the calls to WriteAction()
outside of the SqlConnection
scope, I can simply add the SqlConnection
as a parameter to the function so that the SQLCommand
inside the function make use of the same connection, even if that connection is enlisted to a TransactionScope
.
For the few instances where I call WriteAction()
from outside the scope of any SqlConnection
, I can write an overloaded function that looks like this:
public static void WriteAction(MyActionClass action)
{
using (TransactionScope transactionScope = new TransactionScope())
{
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
WriteAction(action, sqlConnection);
}
transactionScope.Complete();
}
}
Does this look like a good idea or am I going to rue this decision in another two years?