예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
 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);
         }
     }
 }