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