4

I am trying to dynamically create a linq expression at runtime using PredicateBuilder from http://www.albahari.com/nutshell/predicatebuilder.aspx.

I currently have a method that takes a list of criteria objects, and then parses those into multiple predicates much as described in this post.

So currently, my code supports the following scenario:

WHERE 
    ((a == <val1>) AND (b == <val2>) AND (c == <val3>))
OR
    ((a == <val4>) AND (b == <val2>) AND (c == <val3>))

But I need it to work like this:

WHERE 
    ((a == <val1> OR a == <val4>) AND (b == <val2>) AND (c == <val3>))
OR
    ((a == <val7>) AND (b == <val5>) AND (c == <val6>))

How can I make it so that I can "group" two "ORs" together so the logic flows properly? I don't want "a OR a AND b AND c", I need "(a OR a) AND b and C".

Community
  • 1
  • 1
Amanda Kitson
  • 5,477
  • 12
  • 49
  • 73

1 Answers1

5

The "dynamic" aspect of these predicates isn't clear at all. Why bother with PredicateBuilder when you could assemble the required expression with && and || expressions (with proper parentheses of course)?

In any case, here's a way to accomplish what you want with PredicateBuilder:

var p1 = PredicateBuilder.False<Foo>()
                         .Or(foo => foo.A == <val1>)
                         .Or(foo => foo.A == <val4>)
                         .And(foo => foo.B == <val2>)
                         .And(foo => foo. C == <val3>);

var p2 = PredicateBuilder.False<Foo>()
                         .Or(foo => foo.A == <val7>)
                         .And(foo => foo.B == <val5>)
                         .And(foo => foo.C == <val6>);

var finalPredicate = p1.Or(p2);

The idea is to create the individual "simple" expressions, and then finally OR them together to produce the final predicate.

Ani
  • 111,048
  • 26
  • 262
  • 307
  • I guess I don't understand the rules applied when linq is doing order of operations. I assumed that a statement that was "Or().Or().And().And()" would yield something like "a is 1 or (a is 4 and b is 2 and c is 3). How does it know to "or" the a's together? – Amanda Kitson Aug 15 '11 at 15:23
  • Just follow the method calls and you will see how: For example, `p1 =((((First) OR (Second)) AND Third) AND Fourth)`. That is the same as your definition by the rules of boolean algebra. By the way, you might also want to look at [Operator precedence and associativity](http://msdn.microsoft.com/en-us/library/aa691323(v=vs.71).aspx) for guidance on how to do it the "normal" way. Just parenthesize when you need to override the default precedence. – Ani Aug 15 '11 at 15:35