如何用Any连接两个表达式来制定EF核心查询

问题描述 投票:0回答:1

我正试图为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. 如果方法是非通用的,则不应该提供类型参数。

我想这是因为我尝试使用了 ExpressionFunc 而非 ParameterExpression 呼叫 Any 方法。

所以我的问题是,是否可以做到这一点,如果可以,如何?先谢谢你

c# expression-trees ef-core-3.0
1个回答
0
投票

试试这个。

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 争论。

© www.soinside.com 2019 - 2024. All rights reserved.