IQueryable <T>. Где () подходящее выражение в где? - PullRequest
3 голосов
/ 13 декабря 2010

У меня очень низкий опыт работы с Expressions в .NET, поэтому я, скорее, прошу вас, ребятаКак я должен - см. Комментарий ниже:

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?

Спасибо

Ответы [ 4 ]

5 голосов
/ 13 декабря 2010

Вы не можете "ИЛИ" лямбды вместе таким образом.Вы действительно хотите "ИЛИ" лямбда-тела вместе.Вот способ сделать это:

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; 
} 

Затем позже:

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);
1 голос
/ 13 декабря 2010

Вы можете взглянуть на Predicatebuilder:

http://www.albahari.com/nutshell/predicatebuilder.aspx

Predicatebuilder позволяет вам запускать очень мощные выражения (И / ИЛИ / НЕ и т. Д. И т. Д.) В очень понятном и простом для понимания виде. Для простых выражений я, конечно, просто свертываю их с нуля и применяю, но для сложных вещей ...

Я фанат этого:)

несколько ссылок на саму SO, которые могут быть полезны:

LINQ to SQL PredicateBuilder

Сгенерированный SQL с PredicateBuilder, LINQPad и оператором ЛЮБОЙ

0 голосов
/ 13 декабря 2010

.Where метод принимает лямбда-выражение в качестве параметра, поэтому вам нужно построить BinaryExpression до полного 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());
0 голосов
/ 13 декабря 2010

Это комбинация двух Func<P, bool> на уровне выражения.

Менее причудливый способ сделать то же самое должен быть:

Func<P, bool> myExpression1 = x => foo1 == true && foo2 == false;
Func<P, bool> myExpression2 = x => ... ;

IQueryable<P> l = l.Where((p) => myExpression1(p) || myExpression2(p));
...