1

多くの繰り返しコードを持つデータ アクセス レイヤーの名前空間があります (ほとんどの場合、コマンド オブジェクトを設定し、ストアド プロシージャを実行して、リストに追加されるデータ セットを返します)。を返すジェネリック ファクトリ メソッドを作成しようとしていますList<T>。私はジェネリックとデリゲートの両方に比較的慣れていません。私の考えは、に追加されるオブジェクトを作成する Func パラメータを持つことでしたList<T>。通常のwhile dataReader.Read()ブロック内で呼び出されます。私の問題は、使用するデータセットの列数がさまざまであることです。

これが私がこれまでに持っているものです:

private static List<T> ListFromDatabase<T,U>(String CommandName, SqlConnection SqlConn, Func<T,U> CreateListObj, 
    List<SqlParameter> ParamList = null)
{
    List<T> returnList = new List<T>();

    using (SqlCommand cmd = new SqlCommand(CommandName,SqlConn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        foreach (SqlParameter sp in ParamList)
        {
            if (sp.Value == null)
                sp.Value = DBNull.Value;
            cmd.Parameters.Add(sp);
        }

        SqlDataReader sdr = cmd.ExecuteReader();
        while (sdr.Read())
        {
            returnList.Add(CreateListObj);
        }
    }

    return returnList;
}

私の現在の理解レベルでは、さまざまな数のパラメーターに対して Func シグネチャを変更する必要がある可能性が高いため、これは不可能かもしれません。これは実行可能ですか、それとも近いですか?そうでない場合、誰かが助けてくれるなら、私は別のアプローチを受け入れます。事前に多くの感謝..

更新:これはまさに私が探していたものです:

データ リーダーからの行を型付けされた結果に変換する

4

3 に答える 3

1

SqlDataReader代理人としてあなたを渡してみませんIDataRecordか?デリゲートは、データレコードから必要なものを取得できます。リーダーの反復制御を維持します。

于 2012-08-14T19:42:39.247 に答える
1

あなたが望むことを行うための最もエレガントな方法はTuple<T1,T2,T3...>、特定の数とタイプの項目を持つ Tuple を受け入れる関数を渡すことによって T を として指定し、Tuple.Create を使用して sdr からの行の内容を使用してその Tuple を生成することです。 . 問題は、DataReader からフィールドを取得するときに、未確定の型のオブジェクトとして出力され、実際の型が文字列であることを知らない場合にそれらを渡す最も安全な方法です。つまり、CreateListObj 関数は文字列を想定し、それらを正しく解析できます (したがって、タプル内の特定の列の順序が期待されます)。

于 2012-08-14T19:39:00.803 に答える
1

私が過去に行ったことは、IDataReader定義されている型のオブジェクトを受け取って返す「ビルダー」メソッドを定義することです (私はそれらをデリゲートではなくジェネリック クラスのメソッドとして持っていましたがFunc<IDataReader, T> 、同じこと。

一般的に、私は呼び出しで使用CommandBehavior.CloseConnectionし、 最初にリスト全体を作成するのではなく、リーダーを保持し、実装し、破棄されたときにリーダー (したがって、基になる接続) を閉じたクラスを返しました (必要があります)。列挙子が実際にまったく列挙されていない場合は、クリーンアップされることに注意してください)。ExecuteReaderIEnumerable<T>

利点は、定義の時点で列の数と型の違いを気にする必要がなく、実装の時点でのみ気にする必要がないことです (私はそれを気にせずにはいられません)。

于 2012-08-14T19:47:30.767 に答える