如何使用 Any link 两个表达式来制定 EF Core 查询

How to link two expressions with Any to formulate an EF Core query

我正在尝试为 EF Core 查询的条件制定表达式。到目前为止,我所拥有的是一个将我的查询结果类型转换为 IEnumerable 的表达式,以及一个将 IEnumerable 类型转换为 bool 的谓词。现在我想 link 他们有任何条件。到目前为止我正在尝试的是:

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. No type arguments should be provided if the method is non-generic.

我想这是因为我尝试使用 FuncExpression 而不是 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);
}

所以你在这里遇到的问题很少。首先你的 select 或表达式 returns IEnumerable 所以你需要从 Enumerable 获取方法(如果你需要处理 IQueryable 的更多工作将需要,例如检查 valueFunction.Body.Type 以实施 IQueryable)。然后你需要 select 正确的方法,因为 Any 是通用的 - 你需要将特定类型设置为类型参数,从而创建一个代表特定构造方法的 MethodInfo 对象(MakeGenericMethod ).最后使用 valueFunction.Body 作为 Call 参数之一。