简体   繁体   English

如何将 LambdaExpression 转换为表达式<Func<T,bool> &gt; 在 C# 中

[英]How to convert LambdaExpression to Expression<Func<T,bool>> in C#

I have the below code that generates LambdaExpression at run time based on my SearchTerm inputs.我有以下代码,它根据我的SearchTerm输入在运行时生成LambdaExpression I'm trying to build a dynamic where clause.我正在尝试构建一个动态的where子句。 However I'm stuck at how to convert from LambdaExpression to Expression<Func<T,bool>>但是我被困在如何从LambdaExpression转换为Expression<Func<T,bool>>

private static Expression<Func<T,bool>> GetSearchAppliedQuery(IEnumerable<SearchTerm> terms)
{
    var parameterExpression = ExpressionHelper.Parameter<T>();
    Expression finalExpression = Expression.Constant(true);
    Expression subExpression = Expression.Constant(false);

    // Build up the LINQ Expression backwards:
    // query = query.Where(x => x.Property == "Value" && (x.AnotherProperty == "Value" || x.SomeAnotherProperty == "Value"));

    foreach (var term in terms)
    {
        var hasMultipleTerms = term.EntityName?.Contains(',') ?? false;

        if (hasMultipleTerms)
        {
            var entityTerms = term.EntityName.Split(',');

            foreach (var entityTerm in entityTerms)
            {
                term.EntityName = entityTerm;

                // x => x.Property == "Value" || x.AnotherProperty == "Value"
                subExpression = Expression.OrElse(subExpression, GetComparisonExpression(term, parameterExpression));
            }
        }

        // x => x.Property == "Value" && x.AnotherProperty == "Value"
        finalExpression = Expression.AndAlso(finalExpression, hasMultipleTerms ? subExpression : GetComparisonExpression(term, parameterExpression));
    }

    // x => x.Property == "Value" && (x.AnotherProperty == "Value" || x.SomeAnotherProperty == "Value")
    var lambdaExpression = ExpressionHelper.GetLambda<T, bool>(parameterExpression, finalExpression);

    // How to do this conversion??
    Expression<Func<T,bool>> returnValue = ..??;

    return returnValue;
}

I'm trying to apply the result of above method to get the query as shown below:我正在尝试应用上述方法的结果来获取查询,如下所示:

public static IQueryable<T> GetQuery(IQueryable<T> inputQuery, ISpecification<T> specification)
{
    var query = inputQuery;

    // modify the IQueryable using the specification's criteria expression
    if (specification.Criteria != null)
    {
        query = query.Where(specification.Criteria);
    }

    ...
    return query;
}

So that my final query will look like,所以我的最终查询看起来像,

query = query.Where(x => x.Property == "Value" && (x.AnotherProperty == "Value" || x.SomeAnotherProperty == "Value"))

Edit-1: Adding the ExpressionHelper.GetLambda method as requested by @Ivan Stoev编辑 1:根据@Ivan Stoev 的要求添加ExpressionHelper.GetLambda方法

public static class ExpressionHelper
{
    public static LambdaExpression GetLambda<TSource, TDest>(ParameterExpression obj, Expression arg)
    {
        return GetLambda(typeof(TSource), typeof(TDest), obj, arg);
    }

    public static LambdaExpression GetLambda(Type source, Type dest, ParameterExpression obj, Expression arg)
    {
        var lambdaBuilder = GetLambdaFuncBuilder(source, dest);
        return (LambdaExpression)lambdaBuilder.Invoke(null, new object[] { arg, new[] { obj } });
    }

    private static MethodInfo GetLambdaFuncBuilder(Type source, Type dest)
    {
        var predicateType = typeof(Func<,>).MakeGenericType(source, dest);
        return LambdaMethod.MakeGenericMethod(predicateType);
    }
}

Am I missing something very basic or doing anything wrong?我是否遗漏了一些非常基本的东西或做错了什么? Please assist.请协助。

The ExpressionHelper.GetLambda<T, bool> method used to obtain the lambda expression hides its actual type, which is the desired Expression<Func<T, bool>> , so all you need is to use a cast operator:用于获取 lambda 表达式的ExpressionHelper.GetLambda<T, bool>方法隐藏了其实际类型,即所需的Expression<Func<T, bool>> ,因此您只需要使用强制转换运算符:

return (Expression<Func<T, bool>>)lambdaExpression;

Or better, either change the result type of ExpressionHelper.GetLambda<TSource, TDest> to Expression<Func<TSource, TDest>> , or don't use that helper method - when you know the generic type arguments at compile time, simply use one if the generic Expression.Lambda methods ( ExpressionHelper.GetLambda<TSource, TDest> seems to be the equivalent of Expression.Lambda<Func<TSource, TDest>> ), eg或者更好的是,将ExpressionHelper.GetLambda<TSource, TDest>的结果类型更改为Expression<Func<TSource, TDest>> ,或者不使用该辅助方法 - 当您在编译时知道泛型类型参数时,只需使用一个如果通用Expression.Lambda方法( ExpressionHelper.GetLambda<TSource, TDest>似乎相当于Expression.Lambda<Func<TSource, TDest>> ),例如

var lambdaExpression = Expression.Lambda<Func<T, bool>>(parameterExpression, finalExpression);

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

相关问题 C#-如何转换Func <T, bool> 到功能 <dynamic, bool> ? - C# - How to convert Func<T, bool> to Func<dynamic, bool>? 如何将LambdaExpression转换为类型化表达式 <Func<T, T> &gt; - How to convert a LambdaExpression to typed Expression<Func<T, T>> 如何转换Func <T,bool> 表达 <Func<T,bool> &gt; - How to convert Func<T,bool> to Expression<Func<T,bool>> 转换表达式 <Func<T,T,bool> &gt;表达 <Func<T,bool> &gt; - Convert Expression<Func<T,T,bool>> to Expression<Func<T,bool>> 是否可以转换表达式 <Func<T, bool> &gt;表达 <Func<MyType, bool> &gt;? - Is it possible to convert Expression<Func<T, bool>> to Expression<Func<MyType, bool>>? 如何转换表达式 <Func<T1, bool> &gt;表达 <Func<T2, bool> &gt; - How to convert Expression<Func<T1, bool>> to Expression<Func<T2, bool>> 如何转换 Linq 表达式<func<object,object,bool> &gt; 表达<func<t1,t2,bool> &gt; </func<t1,t2,bool></func<object,object,bool> - How to convert Linq Expression<Func<object,object,bool>> to Expression<Func<T1,T2,bool>> 将表达式转换为表达式 <Func<T, bool> &gt; - Convert Expression to Expression<Func<T, bool>> 如何将Expression <Func <T,bool >>转换为Predicate <T> - How to convert an Expression<Func<T, bool>> to a Predicate<T> Func <t,bool> vs C#lambda中的手动表达性能 - Func<t, bool> vs Manually expression performance in C# lambda
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM