Lambda类型参数必须从System.Delegate派生

时间:2019-03-05 00:31:09

标签: c# lambda

在一个C#项目中,我想创建一个扩展名,该扩展名将使用属性名称列表并创建动态选择查询。

我发现magic Gist似乎正是在这样做。但是,var lambda = ...不断抛出以下错误

  

Lambda类型参数必须从System.Delegate派生

这是代码

public static IQueryable<dynamic> ToDynamic<T>(this IQueryable<T> query, IEnumerable<String> fields)
{
    var pocoType = typeof(T);

    var itemParam = Expression.Parameter(pocoType, "x");
    var members = fields.Select(f => Expression.PropertyOrField(itemParam, f));
    var addMethod = typeof(IDictionary<string, object>).GetMethod(
                "Add", new Type[] { typeof(string), typeof(object) });


    var elementInits = members.Select(m => Expression.ElementInit(addMethod, Expression.Constant(m.Member.Name), Expression.Convert(m, typeof(object))));

    var expando = Expression.New(typeof(ExpandoObject));
    var lambda = Expression.Lambda<Expression<Func<T, dynamic>>>(Expression.ListInit(expando, elementInits), itemParam);

    return query.Select(lambda.Compile());
}

如何纠正此错误?

1 个答案:

答案 0 :(得分:0)

Expression.Lambda<T>表达式T中被视为 lambda类型参数,该参数必须从System.Delegate 派生。因此,您只需要删除包装的Expression,并且也不需要最后调用Compile,因为IQueryable希望收到Expression<Func<T, F>>而不是Func<T, F>用于IEnumerable

//..
var lambda = Expression.Lambda<Func<T, dynamic>>(Expression.ListInit(expando, elementInits), itemParam);

return query.Select(lambda);