3

我不确定这是否可能。因为我正在和我的伙伴一起编写一个程序,所以我正在尝试学习一些关于 lambda 表达式的知识。所以他有一个与 MS SQL 服务器对话的数据库类。我想对这些类进行一些测试,因此制作了一个简单的紧凑型数据库,在我的 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 的编程风格。有没有办法做到这一点

4

1 回答 1

5

使用工厂函数。如果您只需使用 a DbConnectionfor all 您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);
    }
}

如果您不想将工厂作为参数传递,则可以使用泛型 withnew()

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);
    }
}
于 2013-07-28T20:04:09.180 回答