Inheritance: AliasedExpression
        protected override SqlExpression VisitSelect(SelectExpression select)
        {
            bool saveIsOuterMostSelect = this.isOuterMostSelect;
            try
            {
                this.isOuterMostSelect = false;
                select = (SelectExpression)base.VisitSelect(select);

                bool hasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0;
                bool hasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0;
                bool canHaveOrderBy = saveIsOuterMostSelect || select.Take != null || select.Skip != null;
                bool canReceiveOrderings = canHaveOrderBy && !hasGroupBy && !select.IsDistinct && !AggregateChecker.HasAggregates(select);
                bool canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct;

                if (!canReceiveOrderings && !canPassOnOrderings && this.gatheredOrderings != null)
                    throw new InvalidOperationException("此表达式可能导致排序信息丢失,请尽量把OrderBy,ThenBy之类的调用放到表达式末尾。");
                if (hasOrderBy)
                {
                    this.PrependOrderings(select.OrderBy);
                }
                IEnumerable<OrderByDeclaration> orderings = null;
                if(canReceiveOrderings)
                {
                    orderings = this.gatheredOrderings;
                }
                else if(canHaveOrderBy)
                {
                    orderings = select.OrderBy;
                }

                ReadOnlyCollection<ColumnDeclaration> columns = select.Columns;
                if (this.gatheredOrderings != null)
                {
                    if (canPassOnOrderings)
                    {
                        HashSet<TableAlias> existingAliases = DeclaredAliasGatherer.Gather(select.From);
                        BindResult project = this.RebindOrderings(this.gatheredOrderings, select.TableAlias, existingAliases, select.Columns);
                        this.gatheredOrderings = null;
                        this.PrependOrderings(project.Orderings);
                        columns = project.Columns.ToReadOnly();
                    }
                    else
                    {
                        this.gatheredOrderings = null;
                    }
                }
                return this.UpdateSelect(select, select.TableAlias, columns, select.From, select.Where, orderings, select.GroupBy, select.Skip, select.Take, select.IsDistinct);
            }
            finally
            {
                this.isOuterMostSelect = saveIsOuterMostSelect;
            }
        }
 protected override SqlExpression VisitSelect(SelectExpression select)
 {
     this.aliases.Add(select.TableAlias);
     return select;
 }
 protected override SqlExpression VisitSelect(SelectExpression select)
 {
     if (this.isOuterMostSelect)
     {
         this.isOuterMostSelect = false;
         this.Visit(select.Where);// ?
         this.VisitOrderBy(select.OrderBy);
         this.VisitColumnDeclarations(select.Columns);
     }
     return select;
 }
 public static bool HasAggregates(SelectExpression expression)
 {
     AggregateChecker checker = new AggregateChecker();
     checker.Visit(expression);
     return checker.hasAggregate;
 }
示例#5
0
        protected override SqlExpression VisitSelect(SelectExpression expr)
        {
            if (expr.Columns == null || expr.Columns.Count == 0 || expr.From == null)
                throw new Exception("invalid sql tree!");
            this.Write("SELECT ");
            if(expr.IsDistinct)
            {
                this.Write("DISTINCT ");
            }
            this.VisitColumnDeclarations(expr.Columns);

            this.NewLine(Indentation.Same);
            this.Write("FROM ");
            this.VisitSource(expr.From);

            if(expr.Where != null)
            {
                this.NewLine(Indentation.Same);
                this.Write("WHERE ");
                this.Visit(expr.Where);
            }
            if(expr.GroupBy != null && expr.GroupBy.Count != 0)
            {
                this.NewLine(Indentation.Same);
                this.Write("GROUP BY ");
                this.VisitExpressionList(expr.GroupBy);
            }
            if(expr.OrderBy != null && expr.OrderBy.Count != 0)
            {
                this.NewLine(Indentation.Same);
                this.Write("ORDER BY ");
                this.VisitOrderBy(expr.OrderBy);
            }
            if(expr.Skip != null || expr.Take != null)
            {
                this.NewLine(Indentation.Same);
                this.Write(string.Format("LIMIT {0}, {1}", expr.Skip == null ? 0 : expr.Skip.Value, expr.Take == null ? int.MaxValue : expr.Take.Value));
            }
            return expr;
        }
示例#6
0
 public InExpression(SqlExpression expression, SelectExpression select)
     : base(SqlExpressionType.In)
 {
     this.Expression = expression;
     this.Select = select;
 }