Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
 public bool Equals(E x, E y)
 {
     return(DbExpressionComparer.AreEqual(x, y, checkParameterNames: this.checkParameterNames));
 }