Reputation: 11990
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
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