First off, prior to asking this question I have been researching connection pooling for the better part of my morning. What I've found is that is turned on by default, handled by the application/system, and C#'s System.Data.X namespaces (where X is something like OLEDBConnection / SqlConnection ) handles it automatically.
But as I'm still new to the whole database access and pooling, I am looking for clarification since I wrote a class to handle connections at a higher level.
public abstract class AbstractDatabase<T> where T: where T : System.Data.Common.DbConnection
{
// Take this class's connection string and return a new connection object
public abstract T GetConnection();
public abstract SqlKata.Compilers.Compiler { get; }
// Compile the query and return a DataTable
// This is actually pointing to a static method that uses the IDBConnection interface and logs any errors, but I copied the relavant code here
public virtual DataTable GetDataTable(SqlKata.Query query)
{
using (var Conn = GetConnection())
{
if (Conn.State == ConnectionState.Closed) Conn.Open();
using (var Cmd = Conn.CreateCommand())
{
Cmd.CommandType = CommandType.Text;
Cmd.Connection = Conn;
Cmd.CommandText = Compiler.Compile(Query).ToString(); // the query is fully formed string here
Cmd.Parameters.AddDummyParameter(); // I noticed that without any parameters, this didn't work, so this method adds a dummy, even if the string doesn't have any '?' characters
using (var DR = Cmd.ExecuteReader())
{
DataTable DT = new DataTable();
DT.Load(DR);
return DT;
}
}
}
}
}
public class SomeDatabase : AbstractDatabase<OleDbConnection>
{
// class implementation
}
here is my question:
If I were to somewhere else in my program do something like this:
DataTable Tbl1 = SomeDatabase.GetDataTable(Query1);
DataTable Tbl2 = SomeDatabase.GetDataTable(Query2);
....
DataTable Tbl10 = SomeDatabase.GetDataTable(Query10);
My understanding is that the method's Using ( var Conn = GetConnection())
statement will automatically issue a Conn.Close()
and dispose of the Conn
as the method exits. But connection pooling is automatically enabled, so it will actually reuse that connection almost immediately instead of closing it, correct?
With that level of abstraction, does it make sense to write it like this?
using ( var conn = SomeDatabase.GetConnection())
{
DataTable Tbl1 = SomeDatabase.GetDataTable(Query1);
....
DataTable Tbl10 = SomeDatabase.GetDataTable(Query10);
}
- Would this make any difference?
- Should the method be written to accept the connection that already open ?
- Should the class be written to use the same connection object itself, rather than calling GetConnection() every time ? ( for example, a get-only property that initializes the backing field on first request to it, then all subsequent requests actually receive the backing field's object)