如何在c#中编写一个从查询字符串创建DataReader的助手方法

本文关键字:创建 字符串 查询 DataReader 方法 一个 | 更新日期: 2023-09-27 18:28:37

我想创建一个助手方法,它接受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重载。这是一个好的做法还是有更好的模式?

如何在c#中编写一个从查询字符串创建DataReader的助手方法

当前,连接未关闭;您可以通过告诉读取器拥有连接(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
}