SQLConnection instances dispose via Dapper - c#

I am using ASP.NET web forms unity for DI in my project:
Next, I have installed Dapper in my project to call database resources via my DAL. In my Startup class I have plugged IDbConnection like this so that the Dapper can make use of that IDbConnection everywhere:
container.RegisterInstance<IDbConnection>(new SqlConnection(connectionString));
My question here is that if I use the dbconnection like this in my class, how will the sql connection be diposed when the work is done:
public class MyProvider: IMyProvider
{
private readonly IDbConnection _dbConnection;
public MyProvider(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public async Task<IEnumerable<MyData>> GetMyData()
{
const string sql = #"SELECT * from mytable";
return await _dbConnection.QueryAsync<Content>(sql);
}
}
I am worried about this part "(new SqlConnection(connectionString))" in my start up while setting up the DI hooks. How and when will the SQLConnection be disposed after calling the database calls. There is no using written any where in the above code.
Will Dapper dispose the SQLConnection after making the call? If no, then can you share how to convert the above code to dispose the SQL Connection after making dapper call?

It won't be disposed, because the instance is effectively a Singleton, and is held for the lifetime of the application. This is not the correct way to inject a DB connection.
Instead, you should register a factory method, using RegisterFactory
container.RegisterFactory<IDbConnection>(f => new SqlConnection(connectionString));
Then you can use that to get a new connection and place it in a using block.

Related

.NET Core EF, cleaning up SqlConnection.CreateCommand

I am using .NET Core DI to get DbContext and in my logic I need to execute raw SQL commands also on DB, so for that purpose I am creating DbCommand to execute SQL like this(just an example query, actual one is little complex so not writing here for simplicity):
public string GetId()
{
var cmd = _context.Database.GetDbConnection().CreateCommand();
bool isOpen = cmd.Connection.State == ConnectionState.Open;
if (!isOpen)
{
cmd.Connection.Open();
}
cmd.CommandText = "Select TOP 1 ID from ABC;";
var result = (string)cmd.ExecuteScalar();
if (isOpen)
{
cmd.Connection.Close();
}
return result;
}
My question here is, that I am using GetDbConnection() and CreateCommand() on DbContext, so Do I need to explicitly dispose result of any of those commands(or enclose those in using statement)?
Also the if block to check if cmd.Connection.State is ConnectionState.Open required, if DI is providing with DbContext, that connection will already be open?
BTW we are using AddDbContextPool to register DbContext to enable DbContext pooling if that matters.
My question here is, that I am using GetDbConnection() and CreateCommand() on DbContext, so Do I need to explicitly dispose result of any of those commands(or enclose those in using statement)?
These are different, and the answer is yes for the later, no for the former.
All you need is to follow to simple principle - the code which allocates resource is responsible for cleaning it up.
GetDbConnection (as indicated by the word Get) does not create DbConnection object, but returns the one created and used by the DbContext instance during its lifetime. In this case the DbContext owns the DbConnection, so you shouldn't dispose that object (doing so could break the owner functionality).
From the other side, CreateCommand does create new DbCommand object, so now your code is owning it and is responsible for disposing it when not needed anymore.
The same principle applies to Open / Close. Again, your code is not owning the DbConnection object, so you have to leave it in the same state as it was when you retrieved it. EF Core internally does that when processing commands which need open connection - open it at the beginning, close it when done. Except if it was opened externally, in which case they do nothing. Which is exactly the aforementioned principle - if your code does Open, then it should do Close, do nothing otherwise.
So the code in question should be something like this (note that there is a bug in close logic of your code - the condition for calling Close should be !isOpen, the same used for Open call):
public string GetId()
{
using (var cmd = _context.Database.GetDbConnection().CreateCommand())
{
bool wasOpen = cmd.Connection.State == ConnectionState.Open;
if (!wasOpen) cmd.Connection.Open();
try
{
cmd.CommandText = "Select TOP 1 ID from ABC;";
var result = (string)cmd.ExecuteScalar();
return result;
}
finally
{
if (!wasOpen) cmd.Connection.Close();
}
}
}
It's good practice to use the using statement so it will automatically dispose of the object when you no longer need it.
However, in your scenario, if you are using this as part of a web application, I believe that the _context scope will be created and disposed off after every HTTP Request, so it will automatically dispose any objects created within the _context scope.

Disposing of SQL Connection

I have a SQL class that connects to the DB and retreives a DataTable. I am aware that the SqlConnection must be disposed when finished. I know this can be done using a using block, but is it also acceptable to put the Dispose() call inside the destructor of this class?
Herre is my code:
public class SQLEng
{
//Connection String Property
//Must be set to establish a connection to the database
public string ConnectionString{ get; set; }
SqlConnection _Conn;
//Overridden Constructor enforcing the Connection string to be set when created
public SQLEng(string connectionString)
{
ConnectionString = connectionString;
_Conn = new SqlConnection(connectionString);
}
//ensure the SqlConnection is disposed when destructing this object
public ~SQLEng()
{
_Conn.Dispose();
}
//various other methods to get datatables etc...
}
Basically i wish to have a class variable SqlConnection, rather than instantiate the SqlConnection inside every method that accesses the DB. Is this sound practise?
Your design encourages hanging on to a (presumably open) SqlConnection for long periods of time. Best practice is to open a connection just before you need it and then release (close and dispose) it as soon as you are finished.
Yes, there is some overhead associated with creating new connections; connection pooling alleviates much of that processing time. Worse is keeping many connections alive on the server.
Looking at the source for the Enterprise Library (from the MS Patterns & Practices team), the DAAB creates a connection as needed and disposes it as quickly as possible.
public virtual int ExecuteNonQuery(DbCommand command)
{
using (var wrapper = GetOpenConnection())
{
PrepareCommand(command, wrapper.Connection);
return DoExecuteNonQuery(command);
}
}
protected DatabaseConnectionWrapper GetOpenConnection()
{
DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(this);
return connection ?? GetWrappedConnection();
}
So I would say that is a best practice. In most cases, all you are doing is returning the connection to the connection pool, so really the connection is not closed per se.
If you wish to wrap the SQL Connection class, implement IDisposable and call the connection Dispose() from within your own Dispose() method. More info is here:
Properly disposing of a DbConnection
As to whether or not this is good practice - well, if all your doing is wrapped the SQL connection in another class, I'm not sure what you're achieving. All your methods will still need access to the instance of this class, in which case they could get access to the instance of the connection object by itself.

Is it best to pass an open SqlConnection as a parameter, or call a new one in each method?

If methods/functions I'm going to call involve the need of an open SqlConnection, I will open this up in the method which is calling the function. For example:
protected static void btnSubmit(){
conn.Open();
myMethod(someParam, conn);
conn.Close();
}
protected static void myMethod(object someParam, SqlConnection conn){
//Some SQL commands etc here..
}
I do this so that I:
Only ever open and close 1 SqlConnection per process
However, would it be better to structure my code like so:
protected static void btnSubmit(){
myMethod(someParam);
}
protected static void myMethod(object someParam){
SqlConnection conn = New SqlConnection(".....");
conn.Open();
//Some SQL commands etc here..
conn.Close();
}
The advantage I see of structuring it this way is:
I don't have to pass an extra parameter for each method
If later down the line the method no longer has a SQL command, there is not an unused parameter being called each time
The disadvantage I see to this, is:
If myMethod is a recursive method, then when it calls itself its going to be opening another SqlConnection, and so on, and so on..
If btnSubmit is calling multiple methods which all require a SqlConnection, each one is going to open and close a new connection.
What is the best way of doing this, and which is most commonly practised?
ADO.NET uses connection pooling, so it automatically reuses existing opened connections, even when you think that you are opening a new connection. Having that in mind, there is really no reason to pass a connection through your code (as a parameter). This will make your code much cleaner, with the same performance as when you were passing the connection as a parameter.
More details here
Also (and this is really important), please, use the "using" keyword. That way, you will not have to deal with closing the connection and cleanup, because your code as it is written now doesn't deal with closing the connections, so in a case of some exception you might end up with hitting connection limit on your server. Go with something like this:
using(var connection = new SqlConnection(<connection_string>))
{
connection.Open();
using(var command = connection.CreateCommand())
{
}
}
As you can see, there is no need to call connection.Close() or deal with exceptions and closing the connection in your finally block, because that is a "job" for the "using" block.
Also, one important note...transactions are not passed via connection polling, so if you want to keep your transaction across method calls, you will have to pass your connection (and that is the only reason I can think of why you should do that).
The best pattern to use is Repository+UnitOfWork patterns.
So repository is created and passed the UnitOfWork which contains the connection. After work is done UnitOfWork is disposed.
// Pseudocode
using(UnitOfWork uow = new UnitOfWork())
{
Repository.Init(uow);
Repository.SaveInDb(stuff);
}
And Unit of work:
// PseudoCode
class UnitOfWork : IDisposable
{
public UnitOfWork()
{
conn = new SqlConnection();
conn.Open();
}
public void Dispose()
{
conn.Close();
}
....
}
This is what I always use.
Some people prefer simpler approach where Repository owns connection. This is simpler but in case you need to have a transaction across multiple repositories, it will not work.

work with an already open database connection

This is a little wierd, but I want to check if connection to my database is already open or not? How do I check that? and if open I want to be able to work with it straightaway without going through all the statements:
sqlconnection conn = new sqlconnection("string ...");
Can this be done? I know the connection string and the connection name too. I want to check if this connection is available first and then proceed.
If you know the connection string then the easiest way of obtaining a new usable sql connection is to create a new instance of the SqlConnection class:
using (SqlConnection conn = new SqlConnection("MyConnectionString"))
{
conn.Open();
// Use the connection
}
The .Net framework uses connection pooling and so there is no need to worry about opening efficiency & multiple connections - the above code will either re-use an available existing connection, or create a new one as required.
If you want to save yourself some typing then you might find it useful to create yourself a small helper method or property:
class SqlHelper
{
public static SqlConnection GetConn()
{
SqlConnection returnValue = new SqlConnection("MyConnectionString");
returnValue.Open();
return returnValue;
}
}
Usage:
using (SqlConnection conn = SqlHelper.GetConn())
{
// Use the connection
}
Have you looked at the documentation for SqlConnection?
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx
I believe the "State" property will tell you what you want.
If you are rather asking more generally how you can use an existing connection from a connection pool, this will be done automatically when you create a new SqlConnection with an identical connection string as an active connection.
If you're just trying to avoid writing redundant code, then put it in a class and reuse it.
Although you are probably just using SQL Server it might be good practice to get familiar with all the core interfaces in System.Data since all data providers implement them. I believe the State property on IDbConnection returns the information you are asking for (IDbConnection)
Also you may want to hide that logic in some kind of centralized method:
public static IDbConnection RetrieveConnection(){
if(DataAccess.Connection.State == ConnectionState.Open) return DataAccess.Connection;
conn.Dispose(); //to be clean, I believe this is safe if it's already disposed
//retrieve configured connection string
//create and open connection
return DataAccess.Connection;
}
So maybe DataAccess is some place you can put and retrieve your connection object, but I would avoid having everyone use it directly. Instead have them go through this method that can ensure the connection is usable. I'm just trying to give you ideas.
Also you may want to take it a step further and use something like NHibernate that will manage connections and all that stuff for you. Although that's not always worth the effort if the project is small.
EDIT: made the code a little more explicit
The Façade Design Pattern should help you here. Here's an example.
Façade Pattern (wikipedia);
Façade Design Pattern (Gang of Four).
An "intelligent" façade knows what method needs to connect where, etc. The façade opens the connection and pass it to an underlying piece of code, generally contained in a factory class or something alike.
public class DoSomethingFacade {
private static readonly DoSomethingFactory _doSomethingFactory = new DoSomethingFactory();
public static IList<T> GetList<T>() {
using(IDbConnection connection = OpenConnection("string..."))
return _doSomethingFactory.GetList<T>(connection);
}
public static IDbConnection OpenConnection(string connectionString) {
IDbConnection openedConnection = new SqlConnection(connectionString);
openedConnection.Open();
return openedConnection;
}
}
internal class DoSomethingFactory {
internal DoSomethingFactory() { }
internal IList<T> GetList<T>(IDbConnection connection) {
IList<T> results = new List<T>();
// use connection here without caring about it,
// as it should be provided as an opened available connection.
return results;
}
}

passing DB Connection object to methods

Was wondering if it is recomended to pass a database connection object around(to other modules) or let the method (in the other module) take care of setting it up. I am leaning toward letting the method set it up as to not have to check the state of the connection before using it, and just having the caller pass any needed data to the calling method that would be needed to setup the connection.
Personally I like to use tightly scoped connections; open them late, use them, and close them (in a "using" block, all within the local method). Connection pooling will deal with re-using the connection in most cases, so there is no real overhead in this approach.
The main advantage in passing connections used to be so that you could pass the transaction around; however, TransactionScope is a simpler way of sharing a transaction between methods.
Since the classes are implementation specific, I'd write each to open it's own native transaction. Otherwise, you can use the ado.net factory methods to create the appropriate type from the config file (the provider name).
Personally, I like storing a stack of my current open connection and transactions on top of the Thread Local Storage using SetData and GetData. I define a class that manages my connections to the database and allow it to use the dispose pattern. This saves me the need to pass connections and transactions around, which is something that I think clutters and complicates the code.
I would strongly recommend against leaving it up to the methods to open connections every time they need data. It will leads to a really bad situation where it is both hard to manage transactions throughout the application and too many connections are opened and closed (I know about connection pooling, it is still more expensive to look up a connection from the pool than it is to reuse an object)
So I end up having something along these lines (totally untested):
class DatabaseContext : IDisposable {
List<DatabaseContext> currentContexts;
SqlConnection connection;
bool first = false;
DatabaseContext (List<DatabaseContext> contexts)
{
currentContexts = contexts;
if (contexts.Count == 0)
{
connection = new SqlConnection(); // fill in info
connection.Open();
first = true;
}
else
{
connection = contexts.First().connection;
}
contexts.Add(this);
}
static List<DatabaseContext> DatabaseContexts {
get
{
var contexts = CallContext.GetData("contexts") as List<DatabaseContext>;
if (contexts == null)
{
contexts = new List<DatabaseContext>();
CallContext.SetData("contexts", contexts);
}
return contexts;
}
}
public static DatabaseContext GetOpenConnection()
{
return new DatabaseContext(DatabaseContexts);
}
public SqlCommand CreateCommand(string sql)
{
var cmd = new SqlCommand(sql);
cmd.Connection = connection;
return cmd;
}
public void Dispose()
{
if (first)
{
connection.Close();
}
currentContexts.Remove(this);
}
}
void Test()
{
// connection is opened here
using (var ctx = DatabaseContext.GetOpenConnection())
{
using (var cmd = ctx.CreateCommand("select 1"))
{
cmd.ExecuteNonQuery();
}
Test2();
}
// closed after dispose
}
void Test2()
{
// reuse existing connection
using (var ctx = DatabaseContext.GetOpenConnection())
{
using (var cmd = ctx.CreateCommand("select 2"))
{
cmd.ExecuteNonQuery();
}
}
// leaves connection open
}
For automated testing purposes, it's usually easier to pass it in. This is called dependency injection.
When you need to write tests, you can create a mock database connection object and pass that instead of the real one. That way, your automated tests won't rely on an actual database that needs to be repopulated with data every time.
I personally work to centralize my data access as much as possible, however, if not possible I ALWAYS open a new connection in the other classes, as I find that there are too many other things that can get in the way when passing the actual connection object.
Here is a little more insight into this problem. I have a class that manages db connections, and have 2 classes that implement an interface. One of the classes is for SQL and the other is of OLAP. The manager is the one that knows which connection to use, so it could pass the exact connection to the type, or the type can create his own connection.
You can pass connection objects without any problem (for instance Microsoft Enterprise Library allows static method calls passing in a connection) or you could manage it externally its up to your design, there are not direct technical tradeoffs.
Be careful for portability not to pass an specific connection if your solution will be ported to other databases (meaning don´t pass a SqlConnection it you plan to work with other databases)
Setting up the connection is potentially expensive and potentially adds a round trip. So, again, potentially, the better design is to pass the connection object.
I say potentially, because if you are a Microsoft ADO app, you are probably using a connection pool....
I would suggest that you distinguish between the connection object and its state (open, closed).
You can have a single method (or property) that reads the connection string from web.config. Using the same version of the connection string every time ensures that you will benefit from connection pooling.
Call that method when you need to open a connection. At the very last moment, after setting up all of the SqlCommand properties, open the connection, use it, and then close it. In C#, you can use the using statement to make sure the connection is closed. If not, be sure to close the connection in a finally block.
I would use the web.config
<configuration>
<connectionStrings>
<add name="conn1" providerName="System.Data.SqlClient" connectionString="string here" />
<add name="conn2" providerName="System.Data.SqlClient" connectionString="string here" />
</connectionStrings>
</configuration>
Then you can reference it from anywhere in the application

Categories

Resources