public override Expression?Visit(Expression?expression) { if (this.candidates.Contains(expression !)) { if (expression is ColumnExpression column) { if (!projectTrivialColumns) { return(expression); } if (this.map.TryGetValue(column, out var mapped)) { return(mapped); } mapped = generator.MapColumn(column).GetReference(newAlias); this.map[column] = mapped; return(mapped); } else { if (expression !.Type.UnNullify().IsEnum) { var convert = expression.TryConvert(expression.Type.IsNullable() ? typeof(int?) : typeof(int)); return(generator.NewColumn(convert).GetReference(newAlias).TryConvert(expression.Type)); }
protected internal override Expression VisitSelect(SelectExpression select) { bool isOuterMost = select == outerMostSelect; if (select.IsOrderAlsoByKeys || select.HasIndex || select.Top != null && hasProjectionInProjector) { if (gatheredKeys == null) { gatheredKeys = new List <ColumnExpression>(); } } List <ColumnExpression>?savedKeys = null; if (gatheredKeys != null && (select.IsDistinct || select.GroupBy.HasItems() || select.IsAllAggregates)) { savedKeys = gatheredKeys.ToList(); } if ((AggregateFinder.GetAggregates(select.Columns)?.Any(a => a.AggregateFunction.OrderMatters()) ?? false) && select.From is SelectExpression from) { var oldOuterMostSelect = outerMostSelect; outerMostSelect = from; select = (SelectExpression)base.VisitSelect(select); outerMostSelect = oldOuterMostSelect; } else { select = (SelectExpression)base.VisitSelect(select); } if (savedKeys != null) { gatheredKeys = savedKeys; } List <ColumnDeclaration>?newColumns = null; if (select.GroupBy.HasItems()) { gatheredOrderings = null; if (gatheredKeys != null) { ColumnGenerator cg = new ColumnGenerator(select.Columns); var newKeys = new List <ColumnDeclaration>(); foreach (var ge in select.GroupBy) { var cd = cg.Columns.NotNull().FirstOrDefault(a => DbExpressionComparer.AreEqual(a.Expression, ge)); if (cd != null) { newKeys.Add(cd); } else { newKeys.Add(cg.NewColumn(ge)); } } if (cg.Columns.Count() != select.Columns.Count) { newColumns = cg.Columns.NotNull().ToList(); } gatheredKeys.AddRange(newKeys.Select(cd => new ColumnExpression(cd.Expression.Type, select.Alias, cd.Name))); } } if (select.IsAllAggregates) { if (gatheredKeys != null) { gatheredKeys.AddRange(select.Columns.Select(cd => new ColumnExpression(cd.Expression.Type, select.Alias, cd.Name))); } } if (select.IsDistinct) { gatheredOrderings = null; if (gatheredKeys != null) { gatheredKeys.AddRange(select.Columns.Select(cd => cd.GetReference(select.Alias))); } } if (select.IsReverse && !gatheredOrderings.IsNullOrEmpty()) { gatheredOrderings = gatheredOrderings.Select(o => new OrderExpression( o.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, o.Expression)).ToReadOnly(); } if (select.OrderBy.Count > 0) { this.PrependOrderings(select.OrderBy); } ReadOnlyCollection <OrderExpression>?orderings = null; if (isOuterMost && !IsCountSumOrAvg(select) || select.Top != null) { AppendKeys(); orderings = gatheredOrderings; gatheredOrderings = null; } if (AreEqual(select.OrderBy, orderings) && !select.IsReverse && newColumns == null) { return(select); } return(new SelectExpression(select.Alias, select.IsDistinct, select.Top, (IEnumerable <ColumnDeclaration>?)newColumns ?? select.Columns, select.From, select.Where, orderings, select.GroupBy, select.SelectOptions & ~SelectOptions.Reverse)); }
private static SelectExpression ExtractOrders(SelectExpression sel, out List <OrderExpression>?innerOrders) { if (sel.Top != null || (sel.OrderBy.Count == 0)) { innerOrders = null; return(sel); } else { ColumnGenerator cg = new ColumnGenerator(sel.Columns); Dictionary <OrderExpression, ColumnDeclaration> newColumns = sel.OrderBy.ToDictionary(o => o, o => cg.NewColumn(o.Expression)); innerOrders = newColumns.Select(kvp => new OrderExpression(kvp.Key.OrderType, kvp.Value.GetReference(sel.Alias))).ToList(); return(new SelectExpression(sel.Alias, sel.IsDistinct, sel.Top, sel.Columns.Concat(newColumns.Values), sel.From, sel.Where, null, sel.GroupBy, sel.SelectOptions)); } }