title: Generic Expression tree with 'OR' clause for each supplied property
body: <p>I have created a generic search extension method for IQueryable that enables you to search for a single property to see if a search term is contained within it.  </p>
  
  <p><a href="http://jnye.co/Posts/6/c%23-generic-search-extension-method-for-iqueryable" rel="nofollow noreferrer">http://jnye.co/Posts/6/c%23-generic-search-extension-method-for-iqueryable</a></p>
  
  <p>I now want to enable the user to select multiple properties to search within each, matching if <strong><em>any</em></strong> property contains the text.</p>
  
  <p><strong>The code:</strong></p>
  
  <p>The user enters the following code to perform this search:</p>
  
  <pre><code>string searchTerm = "Essex";
  context.Clubs.Search(searchTerm, club =&gt; club.Name, club =&gt; club.County)
  
  //Note: If possible I would rather something closer to the following syntax...
  context.Clubs.Search(club =&gt; new[]{ club.Name, club.County}, searchTerm);
  // ... or, even better, something similar to this...
  context.Clubs.Search(club =&gt; new { club.Name, club.County}, searchTerm);
  </code></pre>
  
  <p>This will return any golf club with 'Essex' in the Name or as the County.</p>
  
  <pre><code>    public static IQueryable&lt;TSource&gt; Search&lt;TSource&gt;(this IQueryable&lt;TSource&gt; source, string searchTerm, params Expression&lt;Func&lt;TSource, string&gt;&gt;[] stringProperties)
      {
          if (String.IsNullOrEmpty(searchTerm))
          {
              return source;
          }
  
          // The lamda I would like to reproduce:
          // source.Where(x =&gt; x.[property1].Contains(searchTerm)
          //                || x.[property2].Contains(searchTerm)
          //                || x.[property3].Contains(searchTerm)...)
  
          //Create expression to represent x.[property1].Contains(searchTerm)
          var searchTermExpression = Expression.Constant(searchTerm);
  
  
          //Build parameters
          var parameters = stringProperties.SelectMany(prop =&gt; prop.Parameters);
          Expression orExpression = null;
  
          //Build a contains expression for each property
          foreach (var stringProperty in stringProperties)
          {
              var checkContainsExpression = Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);
              if (orExpression == null)
              {
                  orExpression = checkContainsExpression;
              }
  
              //Build or expression for each property
              orExpression = Expression.OrElse(orExpression, checkContainsExpression);
          }
  
          var methodCallExpression = Expression.Call(typeof(Queryable),
                                                     "Where",
                                                     new Type[] { source.ElementType },
                                                     source.Expression,
                                                     Expression.Lambda&lt;Func&lt;TSource, bool&gt;&gt;(orExpression, parameters));
  
          return source.Provider.CreateQuery&lt;TSource&gt;(methodCallExpression);
      }
  </code></pre>
  
  <p><strong>The error</strong></p>
  
  <p><img src="https://i.stack.imgur.com/cM6qa.png" alt="The error"></p>
  
  <p>If I change the number of parameters supplied to 1:</p>
  
  <pre><code>Expression.Lambda&lt;Func&lt;TSource, bool&gt;&gt;(orExpression, parameters.First()));
  </code></pre>
  
  <p>I get a new error:</p>
  
  <p><img src="https://i.stack.imgur.com/Fpl4p.png" alt="The second error"></p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I have written <a href="http://www.ninjanye.co.uk/2013/04/generic-iqueryable-or-search-on.html" rel="nofollow noreferrer">a post on the work discussed in this question</a>.  <a href="https://github.com/ninjanye/SearchExtensions" rel="nofollow noreferrer">Check it out on GitHub</a> too.</p>