Reputation: 61
I want to implement custom .Contains()
method with the following syntax:
static IQueryable<T> IsContainedBy<T, K>(this IQueryable<T> source, List<K> items, Expression<Func<T, K>> exp)
This method should look for coincidence in items
array. Expression<Func<T, K>> exp
provides property of object to be used for comparison. I have written the following code:
private IQueryable<T> WhereIsContainedBy<T, K>(IQueryable<T> source, List<K> items, Expression<Func<T, K>> exp) {
if (items == null || items.Count == 0)
return source;
MethodInfo containsMethod = typeof(List<K>).GetMethod("Contains", new[] { typeof(K) });
MethodCallExpression a =
Expression.Call(Expression.Constant(items), containsMethod, new Expression[] { exp.Body
/* Expression.Constant("31212eb5-cd5d-4f77-858a-a7ddba8e3d2c")*/ });
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(a, Expression.Parameter(typeof(T)));
return source.Where(lambda);
}
But i get the following error:
var source = new List<string>() { "31212eb5-cd5d-4f77-858a-a7ddba8e3d2c" };
var r = WhereIsContainedBy(_context.StageActions, source, a => a.StageActionId);
var a = await r.ToListAsync();
---
Where(s => List<string> { "31212eb5-cd5d-4f77-858a-a7ddba8e3d2c", }.Contains(a.StageActionId))' could not be translated.
But if I use commented Expression.Constant.....
it works just fine.
Upvotes: 1
Views: 727
Reputation: 142213
Try reusing parameter from selector expression (i.e. exp
) instead of creating a new one for resulting expression :
Expression<Func<T, bool>> lambda =
Expression.Lambda<Func<T, bool>>(a, exp.Parameters[0]);
Upvotes: 2