Junior
Junior

Reputation: 11990

Lambda type parameter must be derived from System.Delegate

In a C# project, I want to create an extension that would take a list of property names and create a dynamic select query.

I found magic Gist that seems to be doing exactly that. However, var lambda = ... keeps throwing the following error

Lambda type parameter must be derived from System.Delegate

Here is the code

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());
}

How can I correct this error?

Upvotes: 0

Views: 1252

Answers (1)

Alexander
Alexander

Reputation: 9632

In Expression.Lambda<T> expression T is considered lambda type parameter that must be derived from System.Delegate. So you just need to remove wrapping Expression and also there is no need to call Compile at the end since IQueryable expect to receive Expression<Func<T, F>> and not a Func<T, F> which is for IEnumerable

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

return query.Select(lambda);

Upvotes: 1

Related Questions