title: Build expression tree for LINQ using List<T>.Contains method
body: <h3>Problem</h3>
  
  <p>I'm working on refactoring some <code>LINQ</code> queries for several reports in our web application, and I'm attempting to move some duplicate query predicates into their own <code>IQueryable</code> exension methods so we can reuse them for these reports, and reports in the future. As you can probably infer, I've already refactored the predicate for groups, but the predicate for codes is giving me problems. This is an example of one of the report methods I have so far:</p>
  
  <p>DAL method:</p>
  
  <pre><code>public List&lt;Entities.QueryView&gt; GetQueryView(Filter filter)
  {
      using (var context = CreateObjectContext())
      {
          return (from o in context.QueryViews
                      where (!filter.FromDate.HasValue || o.RepairDate &gt;= EntityFunctions.TruncateTime(filter.FromDate))
                      &amp;&amp; (!filter.ToDate.HasValue || o.RepairDate &lt;= EntityFunctions.TruncateTime(filter.ToDate))
                      select o)
                  .WithCode(filter)
                  .InGroup(filter)
                  .ToList();
      }
  }
  </code></pre>
  
  <p><code>IQueryable</code> Extension:</p>
  
  <pre><code>public static IQueryable&lt;T&gt; WithCode&lt;T&gt;(this IQueryable&lt;T&gt; query, Filter filter)
  {
      List&lt;string&gt; codes = DAL.GetCodesByCategory(filter.CodeCategories);
  
      if (codes.Count &gt; 0)
          return query.Where(Predicates.FilterByCode&lt;T&gt;(codes));
  
      return query;
  }
  </code></pre>
  
  <p>Predicate:</p>
  
  <pre><code>public static Expression&lt;Func&lt;T, List&lt;string&gt;, bool&gt;&gt; FilterByCode&lt;T&gt;(List&lt;string&gt; codes)
  {
      // Method info for List&lt;string&gt;.Contains(code).
      var methodInfo = typeof(List&lt;string&gt;).GetMethod("Contains", new Type[] { typeof(string) });
  
      // List of codes to call .Contains() against.
      var instance = Expression.Variable(typeof(List&lt;string&gt;), "codes");
  
      var param = Expression.Parameter(typeof(T), "j");
      var left = Expression.Property(param, "Code");
      var expr = Expression.Call(instance, methodInfo, Expression.Property(param, "Code"));
  
      // j =&gt; codes.Contains(j.Code)
      return Expression.Lambda&lt;Func&lt;T, List&lt;string&gt;, bool&gt;&gt;(expr, new ParameterExpression[] { param, instance });
  }
  </code></pre>
  
  <p>The problem I'm having is that <code>Queryable.Where</code> doesn't accept a type of <code>Expression&lt;Func&lt;T, List&lt;string&gt;, bool&gt;</code>. The only way I can think of creating this predicate dynamically is to use two parameters, which is the part that is really stumping me.</p>
  
  <p>What I'm not comprehending is the following method works. I can pass the exact lambda expression I am trying to create dynamically, and it correctly filters my data.</p>
  
  <pre><code>public List&lt;Entities.QueryView&gt; GetQueryView(Filter filter)
  {
      // Get the codes here.
      List&lt;string&gt; codes = DAL.GetCodesByCategory(filter.CodeCategories);
  
      using (var context = CreateObjectContext())
      {
          return (from o in context.QueryViews
                      where (!filter.FromDate.HasValue || o.RepairDate &gt;= EntityFunctions.TruncateTime(filter.FromDate))
                      &amp;&amp; (!filter.ToDate.HasValue || o.RepairDate &lt;= EntityFunctions.TruncateTime(filter.ToDate))
                      select o)
                  .Where(p =&gt; codes.Contains(p.Code)) // This works fine.
                  //.WithCode(filter)
                  .InGroup(filter)
                  .ToList();
  
          }
  
      }
  </code></pre>
  
  <h3>Questions</h3>
  
  <ol>
  <li>Can I implement my own <code>Queryable.Where</code> overload? If so, is it even feasible? </li>
  <li>If an overload isn't feasible, is there a way to dynamically construct the predicate <code>p =&gt; codes.Contains(p.Code)</code> without using two parameters?</li>
  <li>Is there an easier way to do this? I feel like I'm missing something.</li>
  </ol>