How to Append to an expression

后端 未结 8 1552
清歌不尽
清歌不尽 2020-12-05 01:46

Based on my question from yesterday:

if I had to append to my existing \'where\' expression, how would i append?

Expression

        
8条回答
  •  情话喂你
    2020-12-05 02:11

    If you encounter a similar problem, you can find all possible solutions in this great topic. Or just use PredicateBuilder is awesome helper for this poporse.

    var predicate = PredicateBuilder.True();
    
    if (filterByClientFName)
    {
        predicate = predicate.And(c => c.ClientFName == searchForClientFName);
    }
    
    if (filterByClientLName)
    {
            predicate = predicate.And(c => c.ClientLName == searchForClientLName);
    }
    
    var result = context.Clients.Where(predicate).ToArray();
    

    It is some builder implementation.

    public static class PredicateBuilder
        {
            // Creates a predicate that evaluates to true.        
            public static Expression> True() { return param => true; }
    
            // Creates a predicate that evaluates to false.        
            public static Expression> False() { return param => false; }
    
            // Creates a predicate expression from the specified lambda expression.        
            public static Expression> Create(Expression> predicate) { return predicate; }
    
            // Combines the first predicate with the second using the logical "and".        
            public static Expression> And(this Expression> first, Expression> second)
            {
                return first.Compose(second, Expression.AndAlso);
            }
    
            // Combines the first predicate with the second using the logical "or".        
            public static Expression> Or(this Expression> first, Expression> second)
            {
                return first.Compose(second, Expression.OrElse);
            }
    
            // Negates the predicate.        
            public static Expression> Not(this Expression> expression)
            {
                var negated = Expression.Not(expression.Body);
                return Expression.Lambda>(negated, expression.Parameters);
            }
    
            // Combines the first expression with the second using the specified merge function.        
            static Expression Compose(this Expression first, Expression second, Func merge)
            {
                // zip parameters (map from parameters of second to parameters of first)
                var map = first.Parameters
                    .Select((f, i) => new { f, s = second.Parameters[i] })
                    .ToDictionary(p => p.s, p => p.f);
    
                // replace parameters in the second lambda expression with the parameters in the first
                var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
    
                // create a merged lambda expression with parameters from the first expression
                return Expression.Lambda(merge(first.Body, secondBody), first.Parameters);
            }
    
            class ParameterRebinder : ExpressionVisitor
            {
                readonly Dictionary map;
    
                ParameterRebinder(Dictionary map)
                {
                    this.map = map ?? new Dictionary();
                }
    
                public static Expression ReplaceParameters(Dictionary map, Expression exp)
                {
                    return new ParameterRebinder(map).Visit(exp);
                }
    
                protected override Expression VisitParameter(ParameterExpression p)
                {
                    ParameterExpression replacement;
                    if (map.TryGetValue(p, out replacement))
                    {
                        p = replacement;
                    }
                    return base.VisitParameter(p);
                }
            }
        }
    

提交回复
热议问题