3
public static MapFrom Map(this IDataReader idr, params string[] columns)
{
     return new MapFrom { Columns = columns };
}
public static IEnumerable<TEntity> To<TEntity>(this MapFrom from, Func<TEntity, object> map)
{
     // logic here.
}    

public IEnumerable<FooEntity> Execute()
{
    using (DbCommand cmd = db.GetStoredProcCommand("GetListOfFoo"))
    {
        using (IDataReader idr = db.ExecuteReader(cmd))
        {
            return idr.Map("FooID", "FooOfPooAmount", "AnotherFooColumn", "BarID")
              .To<FooEntity>(x => new object[]{
                          x.FooID, x.FooOfPooAmount, x.AnotherFoo, x.BarID
            });
         }
     }
}

データリーダーを使って、使いやすく、パフォーマンスも高いシンプルなマッパーを作成したいと思います。式木はあまり使っていませんが、必要な気がします。私がやりたいのは、xとその配列(ラムダ式)の関係を調べ、この関係を使用して値を自動的に適切にマップし、新しいFooエンティティのリストを作成することです。

MapFromは、情報を伝達し、流暢な拡張メソッドを可能にする単なるコンテナーです。

これらのアクロバットのポイントは、関係を指定する簡単な方法を持つことです。別の形式のようなことを簡単に実行できることに気付きましたが、列を「流暢に」リストし[1](列名を文字列、コンマ、次の列名の順に入力するなど)、オブジェクトをリストできるようにしたかったのです。プロパティを順番に並べ、これからマッピングを推測します。上記のToメソッドを実装することは可能ですか?ここで式ツリーは適切ですか?FooEntityプロパティタイプからデータリーダーフィールドの型キャストを簡単に推測できると思います。

[1]この文脈では、「FluentAPI」のように流暢であるという意味ではありません

4

1 に答える 1

3

ここにMapFromクラスを記述しました。列からFooEntityのインスタンスのプロパティに値をコピーし、yield returnステートメントを使用してエンティティのコレクションを返すコードを記述しなければならないので、MapFromクラスに別のメソッドを追加します。

public class MapFrom
{
    private readonly IDictionary<string, string> columnMapDictionary =
        new Dictionary<string, string>();

    public MapFrom(string[] columns)
    {
        foreach (var column in columns)
        {
            columnMapDictionary.Add(column, null);
        }
    }

    public void To<T>(params Expression<Func<T, object>>[] properties)
    {
        var index = 0;
        foreach (var columnMap in columnMapDictionary.ToDictionary(k => k.Key))
        {
            var member = (properties[index++].Body as MemberExpression);
            var propertyName = member.Member.Name;
            columnMapDictionary[columnMap.Key] = propertyName;  
        }
    }
}

次のように使用します。

var mapper = new MapFrom("Name", "Surname");
mapper.To<FooEntity>(p => p.FirstName, p => p.LastName);
于 2012-06-01T21:58:47.887 に答える