我不确定这是否可行。我正在尝试学习一些关于lambda表达式的知识,因为我和我的好友一起写了一个程序。所以他有一个与MS SQL服务器对话的Database类。我想对类进行一些测试,因此制作了一个简单的压缩数据库,在我的TextFixtureSetup中填充表(现在有2个表),然后在拆解时删除所有数据。他的数据库类使用类似这样的东西进行SQL连接
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);
}
}
我想我找到了Jon Skeet使用几乎相同代码回答的帖子。 https://stackoverflow.com/a/1063112/1329396
我认为这很酷,但我的模拟数据库使用SQLCEReader。我做了一些研究,发现他们共享一个共同的班级System.Data.Common.DbDataReader
,它只有一个级别。我没有检查过多少,但我在想是否有可能使用多态风格的方式来使用WithConnection
编程风格,这将允许我使用我的SQLCeDataReader和他的SQLDataReader。有没有办法做到这一点
答案 0 :(得分:5)
使用工厂功能。如果您只需使用DbConnection
来代替所有Actions
,就不需要泛型:
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);
}
}
如果您想要专门化,仅针对SqlConnection
而某些针对SqlCeConnection
的某些操作,那么您可以将其设为通用:
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);
}
}
如果您不想将工厂作为参数传入,可以使用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);
}
}