public static Expression <Func <T, bool> > Combine <T>(Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2, OperationEnum op) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); if (op == OperationEnum.AND) { return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left, right), parameter)); } else if (op == OperationEnum.OR) { return(Expression.Lambda <Func <T, bool> >(Expression.OrElse(left, right), parameter)); } else { throw new NotImplementedException(); } }
public static Expression <Func <T, bool> > AndAlso <T>(this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2) { if (expr1 == null) { throw new ArgumentNullException(nameof(expr1)); } if (expr2 == null) { throw new ArgumentNullException(nameof(expr2)); } var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); Debug.Assert(left != null, "left is null"); Debug.Assert(right != null, "right is null"); return(Expression.Lambda <Func <T, bool> >(Expression.AndAlso(left, right), parameter)); }
/// <summary> /// 按关键词进行过滤 /// </summary> protected virtual IQueryable <TEntity> ApplyKeywordFilter(IQueryable <TEntity> query) { // 无关键字或无过滤条件时跳过 if (string.IsNullOrEmpty(_request.Keyword) || _keywordConditions.Count == 0) { return(query); } // 使用or合并所有表达式 var firstCondition = _keywordConditions.First(); var leftParamExpr = firstCondition.Parameters[0]; var leftBodyExpr = firstCondition.Body; foreach (var condition in _keywordConditions.Skip(1)) { var rightParamExpr = condition.Parameters[0]; var visitor = new ReplaceExpressionVisitor(rightParamExpr, leftParamExpr); var rightBodyExpr = visitor.Visit(condition.Body); leftBodyExpr = Expression.OrElse(leftBodyExpr, rightBodyExpr); } var predicate = Expression.Lambda <Func <TEntity, bool> >(leftBodyExpr, leftParamExpr); return(query.Where(predicate)); }
public static Expression <Func <T, bool> > AndOrCustom <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2, bool isAnd = true) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); if (isAnd) { return(Expression.Lambda <Func <T, bool> >( Expression.AndAlso(left, right), parameter)); } else { return(Expression.Lambda <Func <T, bool> >( Expression.Or(left, right), parameter)); } }
public static Expression <Func <T, bool> > ToExpression <T>(this IEnumerable <FilterRequest> filters) { if (filters == null || !filters.Any()) { return(null); } var properties = typeof(T).GetProperties(ReflectionConstants.SearchPropertyFlags); var param = Expression.Parameter(typeof(T), "p"); List <Expression <Func <T, bool> > > expressions = new List <Expression <Func <T, bool> > >(); foreach (var filter in filters) { var prop = properties.FirstOrDefault(x => x.Name == filter.Field); var propType = prop.PropertyType; Expression <Func <T, bool> > expression = null; if (filter.ValueDateTimeFrom != null || filter.ValueDateTimeTo != null) { Expression <Func <T, bool> > expressionFrom = null; Expression <Func <T, bool> > expressionTo = null; if (filter.ValueDateTimeFrom != null) { expressionFrom = ExpressionHelper.CreateGTEExpression <T>(param, prop.Name, filter.ValueDateTimeFrom.Value); } if (filter.ValueDateTimeTo != null) { expressionTo = ExpressionHelper.CreateLTEExpression <T>(param, prop.Name, filter.ValueDateTimeTo.Value); } if (expressionFrom != null && expressionTo != null) { var leftVisitor = new ReplaceExpressionVisitor(expressionFrom.Parameters[0], param); var left = leftVisitor.Visit(expressionFrom.Body); var rightVisitor = new ReplaceExpressionVisitor(expressionTo.Parameters[0], param); var right = rightVisitor.Visit(expressionTo.Body); expression = ExpressionHelper.CreateAndExpression <T>(param, left, right); } else { expression = expressionFrom ?? expressionTo; } } else if (filter.ValueNumberFrom != null || filter.ValueNumberTo != null) { Expression <Func <T, bool> > expressionFrom = null; Expression <Func <T, bool> > expressionTo = null; if (filter.ValueNumberFrom != null) { expressionFrom = ExpressionHelper.CreateGTEExpression <T>(param, prop.Name, filter.ValueNumberFrom.Value); } if (filter.ValueNumberTo != null) { expressionTo = ExpressionHelper.CreateLTEExpression <T>(param, prop.Name, filter.ValueNumberTo.Value); } if (expressionFrom != null && expressionTo != null) { var leftVisitor = new ReplaceExpressionVisitor(expressionFrom.Parameters[0], param); var left = leftVisitor.Visit(expressionFrom.Body); var rightVisitor = new ReplaceExpressionVisitor(expressionTo.Parameters[0], param); var right = rightVisitor.Visit(expressionTo.Body); expression = ExpressionHelper.CreateAndExpression <T>(param, left, right); } else { expression = expressionFrom ?? expressionTo; } } else if (filter.ValueBool != null) { expression = ExpressionHelper.CreateEqualExpression <T>(param, prop.Name, filter.ValueBool.Value); } else if (filter.ValueList != null) { expression = ExpressionHelper.CreateContainExpression <T>(param, prop.Name, filter.ValueList); } else { expression = ExpressionHelper.CreateContainExpression <T>(param, prop.Name, filter.ValueString, StringComparison.InvariantCultureIgnoreCase); } expressions.Add(expression); } var result = expressions.FirstOrDefault(); for (int i = 1; i < expressions.Count; i++) { var exp = expressions[i]; var leftVisitor = new ReplaceExpressionVisitor(result.Parameters[0], param); var left = leftVisitor.Visit(result.Body); var rightVisitor = new ReplaceExpressionVisitor(exp.Parameters[0], param); var right = rightVisitor.Visit(exp.Body); result = ExpressionHelper.CreateAndExpression <T>(param, left, right); } return(result); }