title: Linq-to-SQL: Combining (OR'ing) multiple "Contains" filters?
body: <p>I'm having some trouble figuring out the best way to do this, and I would appreciate any help.   </p>
  
  <p>Basically, I'm setting up a filter that allows the user to look at a history of audit items associated with an arbitrary "filter" of usernames.   </p>
  
  <p>The datasource is a SQL Server data base, so I'm taking the IQueryable "source" (either a direct table reference from the db context object, or perhaps an IQueryable that's resulted from additional queries), applying the WHERE filter, and then returning the resultant IQueryable object....but I'm a little stumped as to how to perform OR using this approach.   </p>
  
  <p>I've considered going the route of Expressions because I know how to OR those, but I haven't been able to figure out quite how to do that with a "Contains" type evaluation, so I'm currently using a UNION, but I'm afraid this might have negative impact on performance, and I'm wondering if it may not give me exactly what I need if other filters (in addition to user name filtering shown here) are added in an arbirary order.</p>
  
  <p>Here is my sample code:</p>
  
  <pre><code>public override IQueryable&lt;X&gt; ApplyFilter&lt;X&gt;(IQueryable&lt;X&gt; source)
  {
      // Take allowed values...
      List&lt;string&gt; searchStrings = new List&lt;string&gt;();
  
      // &lt;SNIP&gt; (This just populates my list of search strings)
  
      IQueryable&lt;X&gt; oReturn = null;
  
      // Step through each iteration, and perform a 'LIKE %value%' query
      string[] searchArray = searchStrings.ToArray();
      for (int i = 0; i &lt; searchArray.Length; i++)
      {
          string value = searchArray[i];
          if (i == 0)
              // For first step, perform direct WHERE
              oReturn = source.Where(x =&gt; x.Username.Contains(value));
          else
              // For additional steps, perform UNION on WHERE
              oReturn = oReturn.Union(source.Where(x =&gt; x.Username.Contains(value)));
      }
      return oReturn ?? source;
  }
  </code></pre>
  
  <p>This feels like the wrong way to do things, but it does seem to work, so my question is first, is there a better way to do this?   Also, is there a way to do a 'Contains' or 'Like' with Expressions?</p>
  
  <p>(Editted to correct my code:  In rolling back to working state in order to post it, I apparently didn't roll back quite far enough :) )</p>
  
  <p>=============================================</p>
  
  <p><strong>ETA: Per the solution given, here is my new code (in case anyone reading this is interested):</strong></p>
  
  <pre><code>public override IQueryable&lt;X&gt; ApplyFilter&lt;X&gt;(IQueryable&lt;X&gt; source)
  {
      List&lt;string&gt; searchStrings = new List&lt;string&gt;(AllowedValues);
  
      // &lt;SNIP&gt; build collection of search values 
  
      string[] searchArray = searchStrings.ToArray();
  
      Expression&lt;Func&lt;X, bool&gt;&gt; expression = PredicateBuilder.False&lt;X&gt;();
  
      for (int i = 0; i &lt; searchArray.Length; i++)
      {
          string value = searchArray[i];
          expression = expression.Or(x =&gt; x.Username.Contains(value));
      }
      return source.Where(expression);
  }
  </code></pre>
  
  <p>(One caveat I noticed:  Following the PredicateBuilder's example, an empty collection of search strings will return false (false || value1 || ... ), whereas in my original version, I was assuming an empty list should just coallesce to the unfiltered source.   As I thought about it more, the new version seems to make more sense for my needs, so I adopted that)</p>
  
  <p>=============================================</p>