我正试图为EF Core查询的一个条件制定一个Expression。到目前为止,我所拥有的是一个表达式,将我的查询结果类型转换为一个 IEnumerable
的类型的前提条件。IEnumerable
将其转化为 bool
. 现在我想把它们和一个Any条件联系起来。到目前为止,我所尝试的是这样的。
public static Expression<Func<TIn, bool>> Any<TIn, T>(
Expression<Func<TIn, IEnumerable<T>>> valueFunction,
Expression<Func<T, bool>> predicate)
{
var call = Expression.Call(typeof(Queryable), nameof(Queryable.Any), new[] { typeof(T) }, value, predicate);
return Expression.Lambda<Func<TIn, bool>>(call);
}
这将引发以下异常
System.InvalidOperationException : No generic method 'Any' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. 如果方法是非通用的,则不应该提供类型参数。
我想这是因为我尝试使用了 Expression
的 Func
而非 ParameterExpression
呼叫 Any
方法。
所以我的问题是,是否可以做到这一点,如果可以,如何?先谢谢你
试试这个。
public static Expression<Func<TIn, bool>> Any<TIn, T>(
Expression<Func<TIn, IEnumerable<T>>> valueFunction,
Expression<Func<T, bool>> predicate)
{
var method = typeof(Enumerable).GetMethods()
.Where(mi => mi.Name =="Any" && mi.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(typeof(T));
var call = Expression.Call(method, valueFunction.Body, predicate);
return Expression.Lambda<Func<TIn, bool>>(call, valueFunction.Parameters);
}
所以你在这里有几个问题 首先,你的选择器表达式返回 IEnumerable
所以你需要从 Enumerable
(如果你将需要处理 IQueryable
'的一点点工作将需要,像检查 valueFunction.Body.Type
落实 IQueryable
). 然后你需要选择正确的方法,由于 Any
是通用的--你需要为类型参数设置特定的类型,从而创建一个表示特定构造方法的MethodInfo对象(MakeGenericMethod
). 最后使用 valueFunction.Body
为其中一个 Call
争论。