Reputation: 2409
I'm not sure if this is possible. I'm trying to learn a little bit about lambda expressions because of a program that I am writing with my buddy. So he has a Database class that talks with a MS SQL server. I wanted to do some testing on the classes and so made a simple Compact Database that in my TextFixtureSetup I populate the tables (2 tables right now) and then in teardown I delete all the data. his database class uses something like this for his SQL connection
protected void WithConnection(Action<SqlConnection> sqlBlock)
{
try
{
using (SqlConnection connection = new SqlConnection(this.ConnectionString))
{
connection.Open();
sqlBlock(connection);
}
}
catch (Exception ex)
{
Console.WriteLine(@"Exception during database connection: {0}", ex);
}
}
I think I found a post that Jon Skeet answered using almost the same code. https://stackoverflow.com/a/1063112/1329396
I think that this is cool, but my mock database uses SQLCEReader. I did a little research and found that they share a common class System.Data.Common.DbDataReader
and it is only one level up. I haven't checked much with it, but i was thinking about if it was possible to use a polymorphic style way to use the WithConnection
style of programming that would allow me to use my SQLCeDataReader and his SQLDataReader. Is there a way to do this
Upvotes: 3
Views: 294
Reputation: 10781
Use a factory function. If you can get by with just using a DbConnection
for all your Actions
you don't need generics:
protected void WithConnection(Action<DbConnection> sqlBlock, Func<DbConnection> dbCxnFactory)
{
try
{
using (DbConnection connection = dbCxnFactory())
{
connection.ConnectionString = this.ConnectionString;
connection.Open();
sqlBlock(connection);
}
}
catch (Exception ex)
{
Console.WriteLine(@"Exception during database connection: {0}", ex);
}
}
If you want to specialize, some actions to SqlConnection
only and some to SqlCeConnection
only, then you can make it generic:
protected void WithConnection<T>(Action<T> sqlBlock, Func<T> dbCxnFactory) where T : DbConnection
{
try
{
using (T connection = dbCxnFactory())
{
connection.ConnectionString = this.ConnectionString;
connection.Open();
sqlBlock(connection);
}
}
catch (Exception ex)
{
Console.WriteLine(@"Exception during database connection: {0}", ex);
}
}
If you don't want to pass in the factory as a parameter, you can use a generic with new()
protected void WithConnection<TCxn>(Action<TCxn> sqlBlock) where TCxn : DbConnection, new()
{
try
{
using (var cxn = new TCxn())
{
cxn.ConnectionString = this.ConnectionString;
cxn.Open();
sqlBlock(cxn);
}
}
catch (Exception ex)
{
Console.WriteLine(@"Exception during database connection: {0}", ex);
}
}
Upvotes: 5