IQueryable<T>。包含带有表达式参数的表达式树

IQueryable<T>.Contains Expression Tree with Expression parameter

我想使用以下语法实现自定义 .Contains() 方法:

static IQueryable<T> IsContainedBy<T, K>(this IQueryable<T> source, List<K> items, Expression<Func<T, K>> exp)

此方法应在 items 数组中寻找巧合。 Expression<Func<T, K>> exp 提供 属性 个对象用于比较。我写了下面的代码:

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

但我收到以下错误:

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.

但是如果我使用注释 Expression.Constant..... 它工作得很好。

尝试重新使用选择器表达式(即 exp)中的参数,而不是为结果表达式创建一个新参数:

Expression<Func<T, bool>> lambda = 
    Expression.Lambda<Func<T, bool>>(a, exp.Parameters[0]);