title: Compose LINQ-to-SQL predicates into a single predicate
body: <p>(An earlier question, <a href="https://stackoverflow.com/questions/3782799/recursively-compose-linq-predicates-into-a-single-predicate">Recursively (?) compose LINQ predicates into a single predicate</a>, is similar to this but I actually asked the wrong question... the solution there satisfied the question as posed, but isn't actually what I need. They are different, though. Honest.)</p>
  
  <p>Given the following search text:</p>
  
  <pre><code>"keyword1 keyword2 ... keywordN"
  </code></pre>
  
  <p>I want to end up with the following SQL:</p>
  
  <pre><code>SELECT [columns] FROM Customer 
    WHERE (
          Customer.Forenames LIKE '%keyword1%' 
          OR 
          Customer.Forenames LIKE '%keyword2%'
          OR
          ...
          OR
          Customer.Forenames LIKE '%keywordN%'
      ) AND (
          Customer.Surname LIKE '%keyword1%' 
          OR 
          Customer.Surname LIKE '%keyword2%'
          OR
          ....
          OR
          Customer.Surname LIKE '%keywordN%'
      )
  </code></pre>
  
  <p>Effectively, we're splitting the search text on spaces, trimming each token, constructing a multi-part OR clause based on each , and then AND'ing the clauses together.</p>
  
  <p>I'm doing this in Linq-to-SQL, and I have no idea how to dynamically compose a predicate based on an arbitrarily-long list of subpredicates. For a known number of clauses, it's easy to compose the predicates manually: </p>
  
  <pre><code>dataContext.Customers.Where(
      ( 
        Customer.Forenames.Contains("keyword1") 
        ||
        Customer.Forenames.Contains("keyword2")
      ) &amp;&amp; (
        Customer.Surname.Contains("keyword1") 
        ||
        Customer.Surname.Contains("keyword2")
      )
  );
  </code></pre>
  
  <p>In short, I need a technique that, given two predicates, will return a single predicate composing the two source predicates with a supplied operator, but restricted to the operators explicitly supported by Linq-to-SQL. Any ideas?</p>