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;
..
System.Linq.Expressions.Expression<Func<P, bool>> myExpression = null;
..
myExpression1 = x => foo1 == true && foo2 == false;
myExpression2 = x => ... ;
..
BinaryExpression resultExpression = System.Linq.Expressions.Expression.OrElse(myExpression1, myExpression2);
..
IQueryable<P> l = l.Where(?resultExpression?); // how to transform BinaryExpression to the suitable type?
Thank you
The IQueryable interface inherits the IEnumerable interface so that if it represents a query, the results of that query can be enumerated. Enumeration causes the expression tree associated with an IQueryable object to be executed. The definition of "executing an expression tree" is specific to a query provider.
IQueryable is executed. // // Returns: // A System.Type that represents the type of the element(s) that are returned when. // the expression tree associated with this object is executed.
What is IQueryable? IQueryable<T> is a C# interface that lets you query different data sources. The type T specifies the type of the data source that you're querying. Under the hood, IQueryable uses expression trees that translate LINQ queries into the query language for the data provided.
The major difference between IQueryable and IEnumerable is that IQueryable executes query with filters whereas IEnumerable executes the query first and then it filters the data based on conditions.
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);
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With