using System; using System.Linq; using System.Linq.Expressions; namespace CRM.Core.BLL { public static class PredicateExtensionses { public static Expression> True() { return f => true; } public static Expression> False() { return f => false; } public static Expression> And(this Expression> expLeft, Expression> expRight) { var candidateExpr = Expression.Parameter(typeof(T), "candidate"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body); var right = parameterReplacer.Replace(expRight.Body); var body = Expression.And(left, right); return Expression.Lambda>(body, candidateExpr); } public static Expression> Or(this Expression> expLeft, Expression> expRight) { var candidateExpr = Expression.Parameter(typeof(T), "candidate"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body); var right = parameterReplacer.Replace(expRight.Body); var body = Expression.Or(left, right); return Expression.Lambda>(body, candidateExpr); } /// /// And ((a or b )and (x or d))关系,但是and后面里面的关系是Or的关系,如 a.resid='' and ((a.channel>=1 and a.channel<10) or (a.channel>=50 and a.channel<60)) /// /// /// /// /// public static Expression> AndListOr(this Expression> expLeft, Expression>[] predicates) { var candidateExpr = Expression.Parameter(typeof(T), "candidate"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body); Expression> lambda = predicates[0]; for (int i = 1; i < predicates.Length; i++) { lambda = lambda.Or(predicates[i]); } var right = parameterReplacer.Replace(lambda.Body); var body = Expression.And(left, right); return Expression.Lambda>(body, candidateExpr); } /// /// 传入条件之间为OR查询 /// /// /// /// /// public static IQueryable WhereOR(this IQueryable source, params Expression>[] predicates) { if (source == null) throw new ArgumentNullException("source"); if (predicates == null) throw new ArgumentNullException("predicates"); if (predicates.Length == 0) return source.Where(x => true); if (predicates.Length == 1) return source.Where(predicates[0]); Expression> lambda = predicates[0]; for (int i = 1; i < predicates.Length; i++) { lambda = lambda.Or(predicates[i]); } return source.Where(lambda); } //public static Expression> Or(this Expression> first, Expression> second) //{ // return ParameterRebinder.Compose(first, second, Expression.Or); //} } //public class ParameterRebinder : ExpressionVisitor //{ // public static Expression Compose(Expression first, Expression second, Func merge) // { // // build parameter map (from parameters of second to parameters of first) // var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); // // replace parameters in the second lambda expression with parameters from the first // var secondBody = ReplaceParameters(map, second.Body); // // apply composition of lambda expression bodies to parameters from the first expression // return Expression.Lambda(merge(first.Body, secondBody), first.Parameters); // } //} internal class ParameterReplacer : ExpressionVisitor { public ParameterReplacer(ParameterExpression paramExpr) { this.ParameterExpression = paramExpr; } public ParameterExpression ParameterExpression { get; private set; } public Expression Replace(Expression expr) { return this.Visit(expr); } protected override Expression VisitParameter(ParameterExpression p) { return this.ParameterExpression; } } }