title: Dynamic LINQ Like
body: <p>How to write a dynamic LINQ method for <code>Like</code> clause.</p>
  
  <p>For reference, there is <a href="https://stackoverflow.com/questions/41244/dynamic-linq-orderby">Dynamic LINQ OrderBy on IEnumerable&lt;T&gt; / IQueryable&lt;T&gt;</a>. I am looking for a similar one for dynamic <code>Like</code> clause.</p>
  
  <p>I have the following extension methods for like:</p>
  
  <pre><code>public static IQueryable&lt;T&gt; Like&lt;T&gt;(this IQueryable&lt;T&gt; source, string propertyName, 
                                      string keyword)
  {
      var type = typeof(T);
      var property = type.GetProperty(propertyName);
      var parameter = Expression.Parameter(type, "p");
      var propertyAccess = Expression.MakeMemberAccess(parameter, property);
      var constant = Expression.Constant("%" + keyword + "%");
      var methodExp = Expression.Call(
          null, 
          typeof(SqlMethods).GetMethod("Like", new[] { typeof(string), typeof(string) }),
          propertyAccess, 
          constant);
      var lambda = Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(methodExp, parameter);
      return source.Where(lambda);
  }
  </code></pre>
  
  <p>The above method gives an error</p>
  
  <blockquote>
    <p>Method 'Boolean Like(System.String, System.String)' cannot be used on the client; it is only for translation to SQL.</p>
  </blockquote>
  
  <p>The other method which is somehow modified from <a href="https://stackoverflow.com/questions/41244/dynamic-linq-orderby">Dynamic LINQ OrderBy on IEnumerable&lt;T&gt; / IQueryable&lt;T&gt;</a>:</p>
  
  <pre><code>public static IQueryable&lt;T&gt; ALike&lt;T&gt;(this IQueryable&lt;T&gt; source, string property, 
                                       string keyword)
  {
      string[] props = property.Split('.');
      Type type = typeof(T);
      ParameterExpression arg = Expression.Parameter(type, "x");
      Expression expr = arg;
  
      foreach (string prop in props)
      {
          // use reflection (not ComponentModel) to mirror LINQ
          PropertyInfo pi = type.GetProperty(prop);
          expr = Expression.Property(expr, pi);
          type = pi.PropertyType;
      }
      var constant = Expression.Constant("%" + keyword + "%");
      var methodExp = Expression.Call(
          null, 
          typeof(SqlMethods).GetMethod("Like", new[] { typeof(string), typeof(string) }), 
          expr, 
          constant);
      Type delegateType = typeof(Func&lt;,&gt;).MakeGenericType(typeof(T), type);
      LambdaExpression lambda = Expression.Lambda(delegateType, methodExp, arg);
      object result = typeof(Queryable).GetMethods().Single(
              method =&gt; method.IsGenericMethodDefinition
                      &amp;&amp; method.GetGenericArguments().Length == 2
                      &amp;&amp; method.GetParameters().Length == 2)
              .MakeGenericMethod(typeof(T), type)
              .Invoke(null, new object[] { source, lambda });
      return (IQueryable&lt;T&gt;)result;
  }
  </code></pre>
  
  <p>The above method gives an error:</p>
  
  <blockquote>
    <p>Expression of type 'System.Boolean' cannot be used for return type 'System.String'</p>
  </blockquote>
  
  <p>Any ideas on this?</p>