views:

98

answers:

1

Is there any way I can combine list of expressions into one? I have List<Expression<Child, bool>> expList and trying to combine into one (AndAlso) and get

Expression<Child, bool> combined = Combine(expList);

Intended usage for combined expression is this:

//type of linqFilter is IQueryable<Parent>
linqFilter = linqFilter.SelectMany(p => p.Child).
         Where(combined).Select(t=> t.Parent); 

I am trying something like this:

var result = expList.Cast<Expression>().
Aggregate((p1, p2) => Expression.AndAlso(p1, p2));

But getting an exception

{"The binary operator AndAlso is not defined for the types 'System.Func`2[Child,System.Boolean]' and 'System.Func`2[Child,System.Boolean]'."}
+1  A: 

Try this its a builder so you would have to recursively call it for each in expList

public Expression<Func<T, bool>> Combine<T>(Expression<Func<T, Boolean>> first, Expression<Func<T, Boolean>> second)
{

   var toInvoke= Expression.Invoke(second, first.Parameters.Cast<Expression>());

   return (Expression.Lambda<Func<T, Boolean>>(Expression.AndAlso(first.Body, toInvoke), first.Parameters));

}
Nix
Thanks for reply. Do you know why this exception btw?
Victor
The exception above ? "The binary... " ? And is it caused by the block in the answer or in the question?
Nix
In the question - at the line above that
Victor
Thew only problem is that in the line return (Expression.Lambda<Func<T, Boolean>>(Expression.AndAlso(first.Body, toInvoke), first.Parameters)); looks like compiler cannot resolve "T". If I replace "T" with concrete type, it all works.
Victor
did u try changing Combine -> Combine<T> ?Could have been a typo in my post(i just updated it)
Nix
Ah yeah should've noticed that. Thanks again
Victor