首页 > 解决方案 > 在 C# 中构建动态表达式

问题描述

我正在尝试在应用程序中构建一个动态查询,该查询从前到后发送一些参数,然后使用该参数构建一个表达式。

我基本上有两个主要的课程来完成所有的工作。连接表达式的通用类(称为 PredicateBuilder)和使用它来构建表达式本身的类。

谓词生成器

    public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }

自定义谓词生成器

    public class CustomPredicateBuilder
    {
        public Expression<Func<Ticket, bool>> Build(DtoTicketFilter filter)
        {
            var expression = PredicateBuilder.True<Ticket>();

            // APPROACH 1 - Get an exception
            expression = expression.And(a => filter.IncludeWords.Select(b => a.Content.Contains(b)).Aggregate((c, d) => c && d));

            // APPROACH 2 - It works
            foreach (var word in filter.IncludeWords)
                expression = expression.And(x => x.Content.Contains(word.ToLower()));

            return expression;
        }
    }

正如我所展示的,我尝试了两种方法,当我在查询中使用第一种方法时,我得到了异常。variable 'b' of type 'System.String' referenced from scope '', but it is not defined.

我只想知道为什么我会得到那个异常以及如何解决它。

标签: c#linqasp.net-core

解决方案


推荐阅读