title: Question with PredicateBuilder multiple AND OR
body: <p>I've a question about the PredicateBuilder and I really hope you can give me some advice on how to solve this. I'll try to explain this.</p>
  
  <p>I have the case where people can search for products based on keywords. Each keyword belongs to a keywordgroup, so some real data would be:</p>
  
  <p>KeywordGroup / Keyword</p>
  
  <p>Type - Chain/</p>
  
  <p>Type - Bracelet/</p>
  
  <p>Color - Purple/</p>
  
  <p>Color - Green</p>
  
  <p>Now I want to have the following results:</p>
  
  <p>Between each different KeywordGroup there should be an OR.
  Between each different Keyword inside a KeywordGroup there should be an AND.</p>
  
  <p>So e.g., a user want's to search for only Bracelets with the colors Purlple or Green.</p>
  
  <p>Is this possible with this PredicateBuilder?</p>
  
  <p>This is what I have so far:</p>
  
  <p>================================</p>
  
  <pre><code>/// &lt;summary&gt;
      /// Search for products
      /// &lt;/summary&gt;
      /// &lt;param name="itemsPerPage"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public List&lt;Product&gt; SearchProducts(int from, int max, string sorting, List&lt;Keyword&gt; filter, out int totalitems) {
          try {
  
              var predicate = PredicateBuilder.True&lt;Product&gt;();
              KeywordGroup previousKeywordGroup = null;
              foreach (Keyword k in filter.OrderBy(g=&gt;g.KeywordGroup.SortOrder)) {
                  if (previousKeywordGroup != k.KeywordGroup) {
                      previousKeywordGroup = k.KeywordGroup;
  
                      predicate = predicate.And(p =&gt; p.Keywords.Contains(k));
                  }
                  else
                      predicate = predicate.Or(p =&gt; p.Keywords.Contains(k));
              }
  
              var products = context.Products.AsExpandable().Where(predicate);
  
              //var products = from p in context.Products
              //               from k in p.Keywords
              //               where filter.Contains(k)
              //               select p;
  
              totalitems = products.Distinct().Count();
              if (sorting == "asc")
                  return products.Where(x =&gt; x.Visible == true).Distinct().Skip(from).Take(max).OrderBy(o =&gt; o.SellingPrice).ToList();
              else
                  return products.Where(x =&gt; x.Visible == true).Distinct().Skip(from).Take(max).OrderByDescending(o =&gt; o.SellingPrice).ToList();
          }
          catch (Exception ex) {
              throw ex;
          }
      }
  </code></pre>
  
  <p>================================</p>
  
  <p>It doesn't work, though.</p>
  
  <p>Can you help me out?</p>
  
  <p>Thanks!
  Daniel</p>