Linq PredicateBuilder with conditional filters AND, OR and NOT

We have a project using LINQ to SQL for which I need to rewrite a couple of search pages so that the client can choose whether they want to perform a search and / or search.

At least I am redoing LINQ queries using PredicateBuilder and it seems to me that this works very well. I really have a class containing my predicates, for example:

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

To do a search, I do this (some code is omitted for brevity):

public Expression<Func<Job, bool>> ToLinqExpression()
{
    var predicates = new List<Expression<Func<Job, bool>>>();
    // build up predicates here

    if (SearchType == SearchType.And)
    {
        query = PredicateBuilder.True<Job>();
    }
    else
    {
        query = PredicateBuilder.False<Job>();
    }

    foreach (var predicate in predicates)
    {
        if (SearchType == SearchType.And)
        {
            query = query.And(predicate);
        }
        else
        {
            query = query.Or(predicate);
        }
    }
    return query;
}

While I am satisfied with this, I have two problems:

  • If / else blocks that evaluate the SearchType property feel like they may be a potential code smell.
  • The client now insists on doing "not" / "or not."

2, , , , :

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

, . - , ? LINQ, LINQ .

+5
1

, if/else :

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

'and not' / 'or not' ! .

PD: , foreach ?, , , , .

EDIT: , , - :

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

NegateExp :

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

?

+8

All Articles