Difference between PredicateBuilder<True> and PredicateBuilder<False>?
Asked Answered
K

2

16

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?

Kiloliter answered 22/5, 2013 at 15:15 Comment(5)
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.Tartarus
@O.R.Mapper - Thanks. Here is the documentation: albahari.com/nutshell/predicatebuilder.aspxKiloliter
#15325745Demurrage
I use True with "and" and False with "or" and I always get expected resultsShoemake
If you are using the LinqKit Nuget package the most recent implementation has changed and is created with PredicateBuilder.New<T>() which is equivalent to False.Tetravalent
R
12

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.

Radu answered 26/9, 2017 at 22:33 Comment(0)
S
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

Sebastien answered 26/9, 2017 at 21:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.