简体   繁体   English

如何将两个表达式与 Any 链接以制定 EF Core 查询

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

I'm trying to formulate an Expression for a condition of an EF Core query.我正在尝试为 EF Core 查询的条件制定表达式。 What I have so far is an expression that transforms my query result type to an IEnumerable and a predicate for the type of the IEnumerable that transforms it into a bool .到目前为止,我所拥有的是将我的查询结果类型转换为IEnumerable的表达式和将其转换为boolIEnumerable类型的谓词。 Now I want to link them with an Any condition.现在我想将它们与任何条件联系起来。 What I was trying so far is this:到目前为止我正在尝试的是:

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

This throws the following exception:这会引发以下异常:

System.InvalidOperationException: No generic method 'Any' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. System.InvalidOperationException:在类型“System.Linq.Queryable”上没有通用方法“Any”与提供的类型 arguments 和 arguments 兼容。 No type arguments should be provided if the method is non-generic.如果方法是非泛型的,则不应提供类型 arguments。

I would imagine that this happens because I try to use the Expression of the Func and not a ParameterExpression to call the Any method.我想这是因为我尝试使用FuncExpression而不是ParameterExpression来调用Any方法。

So my question is, is it even possible to do that and if yes how?所以我的问题是,是否有可能做到这一点,如果可以,怎么做? Thank you in advance!先感谢您!

Try this:尝试这个:

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

So you had few issues here.所以你在这里几乎没有问题。 First of all your selector expression returns IEnumerable so you need to get method from Enumerable (if you will need to handle IQueryable 'sa little more work will be needed, like checking valueFunction.Body.Type to implement IQueryable ).首先,您的选择器表达式返回IEnumerable ,因此您需要从Enumerable获取方法(如果您需要处理IQueryable ,则需要做更多的工作,例如检查valueFunction.Body.Type以实现IQueryable )。 Then you need to select correct method and since Any is generic one - you need to set specific type to the type parameters, thus creating a MethodInfo object that represents a particular constructed method ( MakeGenericMethod ).然后你需要 select 正确的方法,因为Any是通用的 - 你需要为类型参数设置特定的类型,从而创建一个 MethodInfo object 代表一个特定的构造方法( MakeGenericMethod )。 And lastly use valueFunction.Body for one of the Call arguments.最后将valueFunction.Body用于Call arguments 之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM