15

I have the code:

   var predicate = PredicateBuilder.True<Value>();

predicate = predicate.And(x => x.value1 == "1");
predicate = predicate.And(x => x.value2 == "2");

var vals = Value.AsExpandable().Where(predicate).ToList();

If I have PredicateBuilder.True<Value>(), it brings back what I expect, but if I have PredicateBuilder.False<Value>(), it brings back 0 records. Can someone explain what the the difference is and why in one scenario I get back 0 records an in the other I get what I expect. I already read the PredicateBuilder documenation, but it was a bit confusing. I have a feeling it has to do with the fact that I am Anding predicates together?

glennsl
  • 28,186
  • 12
  • 57
  • 75
Xaisoft
  • 45,655
  • 87
  • 279
  • 432
  • 3
    I cannot find any documentation on that class, but I would suppose that your calls create an expression that is equivalent to `true && (x.value1 == "1") && (x.value2 == "2")`, which may or may not be evaluate to `true`, depending on your items (hence you get back "what you expect", whatever that is). If you start out from `false`, on the other hand, the expression can *never* evaluate to `true`, because anding `false` results in `false`. Therefore, the predicate expression returns `false` for all items and you don't get back any results. – O. R. Mapper May 22 '13 at 15:27
  • 1
    @O.R.Mapper - Thanks. Here is the documentation: http://www.albahari.com/nutshell/predicatebuilder.aspx – Xaisoft May 22 '13 at 15:38
  • http://stackoverflow.com/questions/15325245/linqkit-predicatebuilder-returns-all-or-non-rows – Amir Feb 15 '15 at 04:57
  • I use True with "and" and False with "or" and I always get expected results – MIKE May 27 '16 at 21:28
  • If you are using the LinqKit Nuget package the most recent implementation has changed and is created with PredicateBuilder.New() which is equivalent to False. – Sean Anderson Nov 24 '19 at 04:07

2 Answers2

11

When using PredicateBuilder to incrementally build a predicate of 0 or more conditions, it is convenient to start off with a "neutral" predicate that can be added to, since you can then just iterate through the conditions and either and or or them together wth the last one. E.g.

var predicate = PredicateBuilder.True<Value>();

foreach (var item in itemsToInclude) {
  predicate = predicate.And(o => o.Items.Contains(item));
}

This would be equivalent to the more straightforward boolean logic:

var predicate = true;

foreach (var item in itemsToInclude) {
  predicate = predicate && o.Items.Contains(item);
}

Which would be equivalent to

true && ((o.Items.Contains(itemsToInclude[0] && o.Items.Contains.itemsToInclude[1]) ...)

Or true && restOfPredicate, which evaluates to true if restOfPredicateis true, and false if restOfPredicate is false. Hence why it's considered neutral.

Starting out with PredicateBuilder.False, however, would be equivalent false && restOfPredicate, which would always evaluate to false.

Similarly for or, starting out with false would be equivalent to false || restOfPredicate, which evaluate to false if restOfPredicate is false and true if restOfPredicate is true. And true || restOfPredicate would always evaluate to true.

Bottom line: Use PredicateBuilder.True as a neutral starting point with PredicateBuilder.And, and PredicateBuilder.False with PredicateBuilder.Or.

glennsl
  • 28,186
  • 12
  • 57
  • 75
0

How it Works The True and False methods do nothing special: they are simply convenient shortcuts for creating an Expression> that initially evaluates to true or false. So the following:

var predicate = PredicateBuilder.True (); is just a shortcut for this:

Expression> predicate = c => true; When you’re building a predicate by repeatedly stacking and/or conditions, it’s useful to have a starting point of either true or false (respectively).

Info complete http://www.albahari.com/nutshell/predicatebuilder.aspx

Nico
  • 31
  • 2