Patrick Desjardins Blog
Patrick Desjardins picture from a conference

How to extend (or add) conditionnal clause to Expression<T>

Posted on: 2012-09-27

If you need to concatenate two expressions (with OR or AND) this can be done easily with the help of the LinqKit library.

The idea is to Invoke both expression with the same model object.

 Expression<Func<Customer, bool>> filter1 = customer => customer.FirstName == "Test"; 
 Expression<Func<Customer, bool>> filter2 = customer => customer.LastName == "Test"; 
 Expression<Func<Customer, bool>> filter3 = customer => filter1 .Invoke(customer) || filter2.Invoke(customer); 

The last step is to use AsExpendable() and to you Expand to the last filter (filter3).

 IEnumerable<Customer> customers = CustomerRepository
 .GetAll()
 .AsExpandable()
 .Where(filter3.Expand())
 .OrderBy(c => c.Id); 

The AsExpendable() method simple create a wrapper around the IQueryable to create a ExpendableQuery. From here, the provider will change with the concrete provider ExpendableQueryProvider which inherit from IQueryProvider. This one will call the .Expand() of the expression.

If you check the source code of the method ExpendableQuery we can see the wrapping.

public static IQueryable<T> AsExpandable<T>(this IQueryable<T> query) { 
  if (query is ExpandableQuery<T>) 
    return query; 
  else 
    return (IQueryable<T>) new ExpandableQuery<T>(query); 
} 

The expand looks like this:

public static Expression<TDelegate> Expand<TDelegate>(this Expression<TDelegate> expr) { 
   return (Expression<TDelegate>) new ExpressionExpander().Visit((Expression) expr); 
} 

It calls the Visit method of the ExpressionExpander from the Expression.

In short, what you have to remember to use LinqKit.dll. It makes your life easier when you manipulate dynamic expression.

So, you have appended two Linq To Entity expressions: http://stackoverflow.com/questions/1266742/append-to-an-expression-linq-c