3

我想创建一个接受 sql 查询作为参数并返回 DataReader 的辅助方法。

我写了这样的东西:

private IDataReader GetReader(String query)
{
    try
    {
        var connection = dbProvider.CreateConnection();
        var command = dbProvider.CreateCommand();
        command.CommandText = query;
        command.Connection = connection;
        command.Connection.Open();
        return command.ExecuteReader();
    }
    catch (Exception ex)
    {
        ...
    }
}

客户端代码如下所示:

public List<FileGroupDetail> LoadGroupDetail()
{
    String query = ...;

    using (IDataReader reader = GetReader(query))
    {
        return reader.Select(...);
    }
}

尽管在所有客户端调用中都使用了 using 语句,但我遇到了与连接池相关的问题(超时、传输级错误……)

我的下一步是添加接受连接作为参数的 GetReader 重载。这是一个好习惯还是有更好的模式?

4

1 回答 1

2

目前,连接没有被关闭;您可以通过告诉读者拥有连接(CommandBehavior.CloseConnection,传递给ExecuteReader)来解决这个问题 - 但这只会解决池饱和问题。如果实际问题是次优/过长的查询,它就无能为力了。但是,我会非常担心:

  • 这种设计不允许参数化
  • 这种设计期望人们与读者一起工作,这……可能不是最佳的

传递连接并在调用者处保留连接的所有权将使 IMO更清晰、更清晰,但是当你这样做时,你可能想看看像“dapper”这样的工具,它可以非常优雅地解决很多问题, 例如:

string region = "North";
using(var conn = dbProvider.CreateConnection()) {
    return conn.Query<Custom>(
        "select * from Customers where Region=@region",
        new { region } // full parameterization, the easy way
    ).ToList(); // Query<T> returns IEnumerable<T>, ideal for LINQ-to-Objects
}
于 2013-08-21T08:48:18.830 回答