1

我正在尝试为 Entity Framework 实现动态投影,以便能够指定要返回的属性列表 ang 得到一个值字典作为结果。

        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() 的人有所帮助。我正在选择一个哈希表,我认为问题是 sql 不知道如何做到这一点,尽管我习惯于看到不同的错误。无论如何,也许尝试

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

因为 sourceModel 是您的 IQueryable (起初我打算在属性上建议 ToList() ,但这已经是 IEnumerable 了。

于 2013-03-19T21:40:26.457 回答