I\'m very low experienced with Expressions
in .NET, that\'s why I rather ask you guys.
How should I - see comment below:
using P = Myclass;
..
S
.Where
method takes a lambda expression as a parameter, so you need to build your BinaryExpression
to a complete LambdaExpression
.
var resultExpression = Expression.OrElse(myExp1, myExp2);
// now the exp is like: p > 100 || p < 10
ParameterExpression parameterExp = Expression.Parameter(typeof(P),"p");
// construct a parameter with its type P, looks like: p =>
LambdaExpression lambdaExp = Expression.Lambda(resultExpression, parameterExp);
// merge the two expressions: p => p > 100 || p < 10
myList.Where(lambdaExp.Compile());
you might want to take a wee look at the Predicatebuilder:
http://www.albahari.com/nutshell/predicatebuilder.aspx
the Predicatebuilder allows you to run up some very powerful expressions (AND/OR/NOT etc, etc) in a very clean and easy to understand way. For simple expressions, I do of course just roll them from scratch and apply but for the complex stuff...
I'm quite a fan of it :)
a few links on SO itself that may be helpful:
LINQ to SQL PredicateBuilder
Generated SQL with PredicateBuilder, LINQPad and operator ANY
You can't "OR" lambdas together that way. You really want to "OR" the lambda bodies together. Here's a method to do that:
public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>(
this IEnumerable<Expression<Func<T, bool>>> filters)
{
Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault();
if (firstFilter == null)
{
Expression<Func<T, bool>> alwaysTrue = x => true;
return alwaysTrue;
}
var body = firstFilter.Body;
var param = firstFilter.Parameters.ToArray();
foreach (var nextFilter in filters.Skip(1))
{
var nextBody = Expression.Invoke(nextFilter, param);
body = Expression.OrElse(body, nextBody);
}
Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param);
return result;
}
Then later:
Expression<Func<P, bool>> myFilter1 = x => foo1 == true && foo2 == false;
Expression<Func<P, bool>> myFilter2 = x => ... ;
..
List<Expression<Func<P, bool>>> filters = new List<Expression<Func<P, bool>>>();
filters.Add(myfilter1);
filters.Add(myfilter2);
..
Expression<Func<P, bool>> resultFilter = filters.OrTheseFiltersTogether();
IQueryable<P> query = query.Where(resultFilter);
Its a combination of two Func<P, bool>
on expression level.
A less fancy way to do the same should be:
Func<P, bool> myExpression1 = x => foo1 == true && foo2 == false;
Func<P, bool> myExpression2 = x => ... ;
IQueryable<P> l = l.Where((p) => myExpression1(p) || myExpression2(p));