首页 > 解决方案 > 可查询的.包含带有表达式参数的表达式树

问题描述

我想.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.....它就可以了。

标签: c#linqentity-framework-coreexpression

解决方案


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

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

推荐阅读