I'm using LinqKit 1.2.3 and I was just trying out how to combine multiple expressions. Basically what I wanted to achieve is "give me results which match A && B && (C || D)".
I made the bellow code as an example:
string[] values = new string[]
{
"1","2","3","11","56",
"2","543","345","13421","562467",
"14324","23452","36789","10001","556876",
"1234","2432423","36456456","187681","50006",
};
ExpressionStarter<String> masterPredicate = PredicateBuilder.New<String>(true);
ExpressionStarter<String> andPredicate = PredicateBuilder.New<String>(true);
ExpressionStarter<String> orPredicate = PredicateBuilder.New<String>(true);
//andPredicate.And(x => x.StartsWith('1')).And(x => x.EndsWith('1')); // doesn't work ???
andPredicate.And(x => x.StartsWith('1'));
andPredicate.And(x => x.EndsWith('1'));
//orPredicate.Or(x => x.Contains('6')).Or(x => x.Contains('0')); // doesn't work ???
orPredicate.Or(x => x.Contains('6'));
orPredicate.Or(x => x.Contains('0'));
//master.And(andPredicate).And(orPredicate); // doesn't work ???
masterPredicate.And(andPredicate);
masterPredicate.And(orPredicate);
string[] filtered = values.Where(masterPredicate).ToArray();
foreach (var item in filtered)
{
Console.WriteLine(item);
}
In the end I got it working, but now I have a question, for example why does
andPredicate.And(x => x.StartsWith('1')).And(x => x.EndsWith('1'));
produce different results then
andPredicate.And(x => x.StartsWith('1'));
andPredicate.And(x => x.EndsWith('1'));
As a matter of fact none of the commented out lines worked the way I thought they would. Can someone shed some light on why this is?
CodePudding user response:
This is expected. PredicateBuilder.And returns a new expression, it doesn't modify the existing one. andPredicate
doesn't change. andPredicate.And(x => x.StartsWith('1'))
returns a new expression that's never used.
var predicate=andPredicate.And(x => x.StartsWith('1')).And(x => x.EndsWith('1'));
is equivalent to :
var pred1=andPredicate.And(x => x.StartsWith('1'));
var predicate=pred1.And(x => x.EndsWith('1'));