IQueryable.Where() suitable Expression in where?

后端 未结 4 1262
自闭症患者
自闭症患者 2021-01-03 02:05

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         


        
相关标签:
4条回答
  • 2021-01-03 02:44

    .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());
    
    0 讨论(0)
  • 2021-01-03 02:54

    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

    0 讨论(0)
  • 2021-01-03 02:57

    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);
    
    0 讨论(0)
  • 2021-01-03 03:01

    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));
    
    0 讨论(0)
提交回复
热议问题