1

.ToDictionary(t => t.Key, t => t.Value) を使用して linq 結果セットを Dictionary コレクションに変換できることはわかっていますが、それ以上のものを探しています。指定されたlinq結果をに変換したいのですIEnumerable<Dictionary<string, object>>が、これが私が探しているものです:

これが私のlinqクエリです:

   var query = from v in dbContext.Persons
                            where !v.InActive
                            select new
                            {
                                v.PersonId,
                                v.Name,
                                v.DateOfBirth,
                            };
this.Persons = query.ToDictionaryCollection();

ToDictionaryCollection は次のようになります。

public static IEnumerable<Dictionary<string, object>> ToDictionaryCollection<T>(this IEnumerable<T> collection) where T : class
        {
            if (collection == null || collection.Count() == 0)
            {
                return new List<Dictionary<string, object>>();
            }
            Type givenType = collection.First().GetType();
            PropertyInfo[] properties = givenType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            return collection
                      .Select(entity =>
                      {
                          return properties.Select(prop => new { Key = prop.Name, Value = prop.GetValue(entity) }).ToDictionary(prop => prop.Key, prop => prop.Value);
                      });
        }

現在の実装では、すべてのエンティティでリフレクションを使用するとペナルティが発生すると思います。ラムダ式ツリーなどを使用して、これを行うより良い方法はありますか?

注: 上記のコードは、Windows Phone 8 および Windows Store 8.1 アプリケーション用です。

ありがとう、ビノイ

4

3 に答える 3

0

プロパティごとに getter デリゲートを作成し、 を呼び出す代わりにそれらを再利用できますprop.GetValue()。これは、繰り返し処理するコレクションが十分に大きい場合に役立ちます。

var properties = typeof (T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
    .Select(
        p =>
        new
            {
                Name = p.Name,
                Getter = (Func<T, object>) Delegate.CreateDelegate(typeof (Func<T, object>), p.GetGetMethod())
            })
    .ToList();

return collection.Select(i => properties.ToDictionary(p => p.Name, p => p.Getter(i)));
于 2013-11-14T21:01:07.090 に答える
0

RouteValueDictionary世界で行われていることと非常に似たようなことをしようとしているようですSystem.Webリフレクションを行う必要性を回避することはできませんが、Microsoftがソース コードを見てこの問題をどのように解決したかを確認することはおそらく有益でしょう。

彼らと同様の Dictionary クラス (" DynamicDictionary" など) を作成した場合、メソッドを次のように変更できます。

if (collection == null)
{
    return new List<Dictionary<string, object>>();
}
return collection.Select(e => new DynamicDictionary(e));

そしてもちろん、特定のディクショナリの実装に密接に結び付けられないように、メソッドがIDictionary(またはインターフェースさえも)を返すようにすることをお勧めします。IReadOnlyDictionary

于 2013-11-14T20:06:45.700 に答える