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; }
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; }
public InExpression(SqlExpression expression, SelectExpression select) : base(SqlExpressionType.In) { this.Expression = expression; this.Select = select; }