Adding OR expressions in a loop in Linq

后端 未结 3 1192
死守一世寂寞
死守一世寂寞 2021-02-05 19:17

I have a variable number of OR conditions that I want to put together into one Linq query.

How do I do this in a loop? Basically, the final query is to

3条回答
  •  长情又很酷
    2021-02-05 19:39

    You'd need to build an expression tree representing all the conditions you were interested in, combined with Expression.OrElse, and then call Where a single time at the end.

    This may be somewhat tricky if your current source is an anonymous type, but it shouldn't be too bad otherwise. Here's a sample - there may be a simpler way of doing the parameter replacement, but this isn't too bad. (Although ExpressionVisitor only works in .NET 4... you'd have to implement something similar yourself if you wanted to use this in .NET 3.5.)

    using System;
    using System.Linq;
    using System.Linq.Expressions;
    
    public class Test
    {
        static void Main()
        {
            IQueryable strings = (new[] { "Jon", "Tom", "Holly", 
                 "Robin", "William" }).AsQueryable();
    
    
            Expression> firstPredicate = p => p.Contains("ll");
            Expression> secondPredicate = p => p.Length == 3;
            Expression combined = Expression.OrElse(firstPredicate.Body,
                                                    secondPredicate.Body);
    
            ParameterExpression param = Expression.Parameter(typeof(string), "p");
            ParameterReplacer replacer = new ParameterReplacer(param);
            combined = replacer.Visit(combined);
    
            var lambda = Expression.Lambda>(combined, param);
    
            var query = strings.Where(lambda);
    
            foreach (string x in query)
            {
                Console.WriteLine(x);
            }
        }
    
        // Helper class to replace all parameters with the specified one
        class ParameterReplacer : ExpressionVisitor
        {
            private readonly ParameterExpression parameter;
    
            internal ParameterReplacer(ParameterExpression parameter)
            {
                this.parameter = parameter;
            }
    
            protected override Expression VisitParameter
                (ParameterExpression node)
            {
                return parameter;
            }
        }
    }
    

提交回复
热议问题