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 に答える