using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace DG.Core { 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.OrElse(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]); var param = Expression.Parameter(typeof(T), "x"); Expression body = Expression.Invoke(predicates[0], param); for (int i = 1; i < predicates.Length; i++) { body = Expression.OrElse(body, Expression.Invoke(predicates[i], param)); } var lambda = Expression.Lambda>(body, param); return source.Where(lambda); } } 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; } } }