title: Linq PredicateBuilder, grouping and operator precedence
body: <p>Here is an example of the problem:</p>
  
  <pre><code>   var source = new LambdasTestEntity[] { 
          new LambdasTestEntity {Id = 1},
          new LambdasTestEntity {Id = 2},          
          new LambdasTestEntity {Id = 3},
          new LambdasTestEntity {Id = 4},          
      };
  
      Expression&lt;Func&lt;LambdasTestEntity, bool&gt;&gt; expression1 = x =&gt; x.Id == 1;
      Expression&lt;Func&lt;LambdasTestEntity, bool&gt;&gt; expression2 = x =&gt; x.Id == 3;
      Expression&lt;Func&lt;LambdasTestEntity, bool&gt;&gt; expression3 = x =&gt; x.Id &gt; 2;
  
      // try to chain them together in a following rule
      // Id == 1 || Id == 3 &amp;&amp; Id &gt; 2
      // as &amp;&amp; has higher precedence, we expect getting two entities
      // with Id=1 and Id=3 
  
      // see how default LINQ works first
      Expression&lt;Func&lt;LambdasTestEntity, bool&gt;&gt; expressionFull = x =&gt; x.Id == 1 || x.Id == 3 &amp;&amp; x.Id &gt; 2;
  
      var filteredDefault = source.AsQueryable&lt;LambdasTestEntity&gt;()
                .Where(expressionFull).ToList();
  
      Assert.AreEqual(2, filteredDefault.Count); // &lt;-this passes
  
      // now create a chain with predicate builder
      var totalLambda = expression1.Or(expression2).And(expression3);
  
      var filteredChained = source.AsQueryable&lt;LambdasTestEntity&gt;()
                .Where(totalLambda).ToList();
  
  
      Assert.AreEqual(2, filteredChained.Count);
      // &lt;- this fails, because PredicateBuilder has regrouped the first expression,
      // so it now looks like this: (Id == 1 || Id == 3) &amp;&amp; Id &gt; 2
  </code></pre>
  
  <p>When I look in Watches for both expressions, I see the following:</p>
  
  <pre><code>expressionFull as it is coming from Linq:
  (x.Id == 1) OrElse ((x.Id == 3) AndAlso (x.Id &gt; 2))
  
  totalLambda for PredicateBuilder:
  ((x.Id == 1) OrElse Invoke(x =&gt; (x.Id == 3), x)) AndAlso Invoke(x =&gt; (x.Id &gt; 2), x)
  </code></pre>
  
  <p>I find it is a bit unsafe to use the PredicateBuilder if it behaves differently from default Linq Expression builder.</p>
  
  <p>Now some questions:</p>
  
  <p>1) Why is Linq creating those groups? Even if I create an Or expression</p>
  
  <pre><code>x =&gt; x.Id == 1 || x.Id == 3 || x.Id &gt; 2
  </code></pre>
  
  <p>I stil get the first two criteria grouped like this:</p>
  
  <pre><code>((x.Id == 1) OrElse (x.Id == 3)) OrElse (x.Id &gt; 2)
  </code></pre>
  
  <p>Why it is not just</p>
  
  <pre><code>(x.Id == 1) OrElse (x.Id == 3) OrElse (x.Id &gt; 2)
  </code></pre>
  
  <p>?</p>
  
  <p>2) Why PredicateBuilder is adding those Invokes? I don't see Invokes in the default Linq expression result, so they seem useless...</p>
  
  <p>3) Is there any other way to construct the expression "offline" and then pass to the default Linq Expression builder? Something like this:</p>
  
  <pre><code>ex = x =&gt; x.Id == 1;
  ex = ex || x.Id == 3;
  ex = ex &amp;&amp; x.Id &gt; 2;
  </code></pre>
  
  <p>and then Linq Expression builder then parses it and creates the same expression as it does for x => x.Id == 1 || x.Id == 3 &amp;&amp; x.Id > 2 (giving &amp;&amp; higher precedence)?
  Or maybe I could tweak the PredicateBuilder to do the same?</p>