Linq PredicateBuilder with conditional AND, OR and NOT filters

后端 未结 1 1984
生来不讨喜
生来不讨喜 2021-02-04 19:23

We have a project using LINQ to SQL, for which I need to rewrite a couple of search pages to allow the client to select whether they wish to perform an and or an or

相关标签:
1条回答
  • 2021-02-04 20:14

    If you are looking for less lines you can replace the if/else with ternary operator:

    query = SearchType == SearchType.And ? PredicateBuilder.True<Job>() : PredicateBuilder.False<Job>();
    
       foreach (var predicate in predicates)
       {
            query = SearchType == SearchType.And ? query.And(predicate) : query.Or(predicate);
       }
    

    for the 'and not' / 'or not' part the ! operator should do the trick.

    PD: Did you test the foreach part is correctly setting the predicates?, as far as i remember you are building the expression that will be executed at later point in time, so you may have a literal reference just to the last set predicate in the final iteration, and that's why you must use a temp variable to save the value of each iteration.

    EDIT: If you want to negate a expression programmatic, that's a tricky one, you can try something like:

    internal static Expression<Func<Job, bool>> Description(string term, bool invert)
            {
               return NegateExp<Func<Job, bool>>(p => p.Description.Contains(term), invert);
            }
    

    And the NegateExp method will be something like:

    public static Expression<TDelegate> NegateExp<TDelegate>(Expression<TDelegate> expression, bool inverse)
            {
                if (inverse)
                {
                    return Expression.Lambda<TDelegate>(Expression.Not(expression.Body), expression.Parameters);
                }
                return expression;
            }
    

    You can take a look at this question for more examples Is there any way to negate a Predicate?

    0 讨论(0)
提交回复
热议问题