1

プロパティのリストを指定して結果として値の辞書を取得できるように、Entity Framework の動的射影を実装しようとしています。

        public static IQueryable<Dictionary<string, object>> ProjectionMap<TSource>
        (IQueryable<TSource> sourceModel, IEnumerable<string> properties) 
    {
        var itemParam = Expression.Parameter(typeof (TSource), "item");

        var addMethod = typeof (Dictionary<string, object>).GetMethod("Add");

        var elements = properties.
            Select(
                property =>
                Expression.ElementInit(addMethod, Expression.Constant(property),
                                       GetPropertyExpression<TSource>(itemParam, property))).
            ToList();

        var newDictionaryExpression =
            Expression.New(typeof (Dictionary<string, object>));

        var dictionaryInit = Expression.ListInit(newDictionaryExpression, elements);

        var projection = Expression.Lambda<Func<TSource, Dictionary<string, object>>>(dictionaryInit, itemParam);

        return sourceModel.Select(projection);
    }

    public static Expression GetPropertyExpression<T>(ParameterExpression parameter, string propertyName) 
    {
        var properties = typeof (T).GetProperties();
        var property = properties.First(p => p.Name == propertyName);
        return Expression.Property(parameter, property);
    }

実行時に次のコードを実行すると例外が発生します

var query = ProjectionMap(db.Posts, new[]{"Subject"});
            var result = query.ToList();

NotSupportedException LINQ to Entities では、単一の要素を持つリスト初期化子項目のみがサポートされています。

コードを修正する方法や、適切に実装する方法についてのアイデアはありますか? 前もって感謝します。

4

1 に答える 1

0

同じエラーが発生しましたが、別の理由である可能性があります (コードを試していません)。これが選択の前に .ToList() を追加したばかりの人に役立つことを願っています。私は Hashtable を選択していましたが、問題は SQL がそれを行う方法を知らなかったことだと思いますが、別のエラーを見ることに慣れています。とにかく、試してみてください

    return sourceModel.ToList().Select(projection);

sourceModel は IQueryable であるため (最初はプロパティで ToList() を提案するつもりでしたが、それはすでに IEnumerable.

于 2013-03-19T21:40:26.457 に答える