public static bool HasAggregates(DbSelectExpression expression)
        {
            var checker = new DbAggregateChecker();

            if (checker != null)
            {
                checker.Visit(expression);
            }

            return(checker.hasAggregate);
        }
 private bool CanJoinOnClient(DbSelectExpression select)
 {
     return
         (
         this.canJoinOnClient &&
         this.currentMember != null &&
         !this.policy.IsDeferLoaded(this.currentMember) &&
         !select.IsDistinct &&
         (select.GroupBy == null || select.GroupBy.Count == 0) &&
         !DbAggregateChecker.HasAggregates(select)
         );
 }
Beispiel #3
0
 private bool CanJoinOnServer(DbSelectExpression select)
 {
     return(select.IsDistinct == false && (select.GroupBy == null || select.GroupBy.Count == 0) && !DbAggregateChecker.HasAggregates(select));
 }
        protected override Expression VisitSelect(DbSelectExpression select)
        {
            bool saveIsOuterMostSelect = this.isOuterMostSelect;

            try
            {
                this.isOuterMostSelect = false;

                select = base.VisitSelect(select) as DbSelectExpression;

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

                if (hasOrderBy)
                {
                    this.PrependOrderings(select.OrderBy);
                }

                if (select.IsReverse)
                {
                    this.ReverseOrderings();
                }

                var orderings = null as IEnumerable <DbOrderExpression>;

                if (canReceiveOrderings)
                {
                    orderings = this.gatheredOrderings;
                }
                else if (canHaveOrderBy)
                {
                    orderings = select.OrderBy;
                }

                var canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct;
                var columns            = select.Columns;

                if (this.gatheredOrderings != null)
                {
                    if (canPassOnOrderings)
                    {
                        var producedAliases = DbDeclaredAliasGatherer.Gather(select.From);
                        var project         = this.RebindOrderings(this.gatheredOrderings, select.Alias, producedAliases, select.Columns);

                        this.gatheredOrderings = null;
                        this.PrependOrderings(project.Orderings);

                        columns = project.Columns;
                    }
                    else
                    {
                        this.gatheredOrderings = null;
                    }
                }

                if (orderings != select.OrderBy || columns != select.Columns || select.IsReverse)
                {
                    select = new DbSelectExpression(select.Alias, columns, select.From, select.Where, orderings, select.GroupBy, select.IsDistinct, select.Skip, select.Take, false);
                }

                return(select);
            }
            finally
            {
                this.isOuterMostSelect = saveIsOuterMostSelect;
            }
        }
Beispiel #5
0
        protected override Expression VisitJoin(DbJoinExpression join)
        {
            join = base.VisitJoin(join) as DbJoinExpression;

            if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply)
            {
                if (join.Right is DbTableExpression)
                {
                    return(new DbJoinExpression(JoinType.CrossJoin, join.Left, join.Right, null));
                }

                if (join.Right is DbSelectExpression select && select.Take == null && select.Skip == null && !DbAggregateChecker.HasAggregates(select) && (select.GroupBy == null || select.GroupBy.Count == 0))
                {
                    var selectWithoutWhere = select.SetWhere(null);
                    var referencedAliases  = DbReferencedAliasGatherer.Gather(selectWithoutWhere);
                    var declaredAliases    = DbDeclaredAliasGatherer.Gather(join.Left);

                    if (referencedAliases != null)
                    {
                        referencedAliases.IntersectWith(declaredAliases);
                    }

                    if (referencedAliases.Count == 0)
                    {
                        var where = select.Where;

                        select = selectWithoutWhere;

                        var pc = DbColumnProjector.ProjectColumns(this.language, where, select.Columns, select.Alias, DbDeclaredAliasGatherer.Gather(select.From));

                        select = select.SetColumns(pc.Columns);

                        where = pc.Projector;

                        var jt = (where == null) ? JoinType.CrossJoin : (join.JoinType == JoinType.CrossApply ? JoinType.InnerJoin : JoinType.LeftOuter);

                        return(new DbJoinExpression(jt, join.Left, select, where));
                    }
                }
            }

            return(join);
        }
Beispiel #6
0
            private static bool CanMergeWithFrom(DbSelectExpression select, bool isTopLevel)
            {
                var fromSelect = GetLeftMostSelect(select.From);

                if (fromSelect == null)
                {
                    return(false);
                }

                if (IsColumnProjection(fromSelect) == false)
                {
                    return(false);
                }

                var selHasNameMapProjection = IsNameMapProjection(select);
                var selHasOrderBy           = select.OrderBy != null && select.OrderBy.Count > 0;
                var selHasGroupBy           = select.GroupBy != null && select.GroupBy.Count > 0;
                var selHasAggregates        = DbAggregateChecker.HasAggregates(select);
                var selHasJoin       = select.From is DbJoinExpression;
                var frmHasOrderBy    = fromSelect.OrderBy != null && fromSelect.OrderBy.Count > 0;
                var frmHasGroupBy    = fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0;
                var frmHasAggregates = DbAggregateChecker.HasAggregates(fromSelect);

                if (selHasOrderBy && frmHasOrderBy)
                {
                    return(false);
                }

                if (selHasGroupBy && frmHasGroupBy)
                {
                    return(false);
                }

                if (select.IsReverse || fromSelect.IsReverse)
                {
                    return(false);
                }

                if (frmHasOrderBy && (selHasGroupBy || selHasAggregates || select.IsDistinct))
                {
                    return(false);
                }

                if (frmHasGroupBy)
                {
                    return(false);
                }

                if (fromSelect.Take != null && (select.Take != null || select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin))
                {
                    return(false);
                }

                if (fromSelect.Skip != null && (select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin))
                {
                    return(false);
                }

                if (fromSelect.IsDistinct && (select.Take != null || select.Skip != null || !selHasNameMapProjection || selHasGroupBy || selHasAggregates || (selHasOrderBy && !isTopLevel) || selHasJoin))
                {
                    return(false);
                }

                if (frmHasAggregates && (select.Take != null || select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin))
                {
                    return(false);
                }

                return(true);
            }