protected override Expression VisitBinary(BinaryExpression binaryExp) { if (binaryExp.NodeType == ExpressionType.AndAlso || binaryExp.NodeType == ExpressionType.OrElse) { //先计算左边的约束结果 this.Visit(binaryExp.Left); this.MakeBooleanConstraintIfNoValue(); var left = _query.Where; //再计算右边的约束结果 this.Visit(binaryExp.Right); this.MakeBooleanConstraintIfNoValue(); var right = _query.Where; //使用 AndOrConstraint 合并约束的结果。 var op = binaryExp.NodeType == ExpressionType.AndAlso ? BinaryOperator.And : BinaryOperator.Or; if (_reverseWhere) { op = binaryExp.NodeType == ExpressionType.AndAlso ? BinaryOperator.Or : BinaryOperator.And; } _query.Where = f.Binary(left, op, right); } else { this.VisitPropertyComparison(binaryExp); } return(binaryExp); }
/// <summary> /// <![CDATA[ /// 将聚合子表达式解析为嵌入式子查询条件。 /// 例如: /// 将表达式 /// book.ChapterList.Cast<Chapter>().Any(c => c.Name == chapterName) /// 转换为: /// f.Exists(f.Query(chapter, /// where: f.And( /// f.Constraint(chapter.Column(Chapter.BookIdProperty), book.IdColumn), /// f.Constraint(chapter.Column(Chapter.NameProperty), chapterName) /// ) /// )) /// SQL: /// SELECT * FROM [Book] b /// WHERE EXISTS( /// SELECT * FROM [Chapter] c /// WHERE c.BookId = b.Id AND /// c.Name = {0} /// ) /// ]]> /// </summary> /// <param name="exp">需要解析的表达式</param> /// <param name="parentQuery"></param> /// <param name="propertyFinder">The property finder.</param> internal IConstraint Build(Expression exp, IQuery parentQuery, PropertyFinder propertyFinder) { _parentQuery = parentQuery; _parentPropertyFinder = propertyFinder; this.Visit(exp); var res = f.Exists(_query); if (!_isAny) { res = f.Not(res); } //如果父查询中需要反转条件,则返回 NOT 语句。 if (propertyFinder.ReverseConstraint) { res = f.Not(res); } //把可空外键的不可空条件,与 Exists 条件合并后返回。 if (propertyFinder.NullableRefConstraint != null) { var op = propertyFinder.ReverseConstraint ? BinaryOperator.Or : BinaryOperator.And; res = f.Binary(propertyFinder.NullableRefConstraint, op, res); } return(res); }
protected override void VisitAndOrConstraint(AndOrConstraint node) { this.Visit(node.Left); var leftWhere = _whereResult; this.Visit(node.Right); var rightWhere = _whereResult; _whereResult = f.Binary(leftWhere, node.IsAnd ? BinaryOperator.And : BinaryOperator.Or, rightWhere); }
private void DealBracket(string part) { if (part == "(") { if (_concat.HasValue && _current != null) { _bracketStack.Push(new StackItem { Concat = _concat.Value, Constraint = _current }); _concat = null; _current = null; } } else { if (_bracketStack.Count > 0) { var outBracket = _bracketStack.Pop(); _current = _f.Binary(outBracket.Constraint, outBracket.Concat, _current); } } }