Expanding on my comment above:
Because it has no concept of operator precedence here. You're literally building the expression tree yourself, and "piping" the results of one method to the next determines order. Thus, the order of the resulting expression is going to be exactly what you specified.
The complete source for PredicateBuilder
is posted here and shows just how simple it is. But it also shows you the source of your problem above. In case you don't want to visit Albahari's site, here's the complete source:
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
The main thing to notice here is that it builds the expression one node at a time, then pipes this node as being the left expression (leaf) of the subsequent node. The Expression.Invoke
call is simply to pipe the parameters from your existing node into the right leaf (the next expression), and the rest is pretty self explanatory.
Edit: I had to do something similar to this (but didn't use PredicateBuilder, built the trees myself using Expression
calls). The main thing to keep in mind is that you just have to process the And/AndAlso
nodes first, and then handle the Or/OrElse
nodes, that way you build the tree with the proper precedence. Unfortunately, building ExpressionTrees
by hand are very much a step-by-step process, so you have to make sure you break each of the steps down into the correct order to get the results you want/need.