示例#1
0
        protected override Expression VisitJoin(DbJoinExpression join)
        {
            join = base.VisitJoin(join) as DbJoinExpression;

            if (join.JoinType == JoinType.CrossJoin && this.currentWhere != null)
            {
                var declaredLeft  = DbDeclaredAliasGatherer.Gather(join.Left);
                var declaredRight = DbDeclaredAliasGatherer.Gather(join.Right);
                var declared      = new HashSet <TableAlias>(declaredLeft.Union(declaredRight));
                var exprs         = this.currentWhere.Split(ExpressionType.And, ExpressionType.AndAlso);
                var good          = exprs.Where(e => CanBeJoinCondition(e, declaredLeft, declaredRight, declared)).ToList();

                if (good.Count > 0)
                {
                    var condition = good.Join(ExpressionType.And);

                    join = this.UpdateJoin(join, JoinType.InnerJoin, join.Left, join.Right, condition);

                    var newWhere = exprs.Where(e => !good.Contains(e)).Join(ExpressionType.And);

                    this.currentWhere = newWhere;
                }
            }

            return(join);
        }
        private void MapAliases(Expression a, Expression b)
        {
            var prodA = DbDeclaredAliasGatherer.Gather(a).ToArray();
            var prodB = DbDeclaredAliasGatherer.Gather(b).ToArray();

            for (int i = 0, n = prodA.Length; i < n; i++)
            {
                this.aliasScope.Add(prodA[i], prodB[i]);
            }
        }
示例#3
0
        public static HashSet <TableAlias> Gather(Expression source)
        {
            var gatherer = new DbDeclaredAliasGatherer();

            if (gatherer != null)
            {
                gatherer.Visit(source);
            }

            return(gatherer.aliases);
        }
示例#4
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);
        }
示例#5
0
        internal virtual Expression GetOuterJoinTest(DbSelectExpression select)
        {
            var aliases     = DbDeclaredAliasGatherer.Gather(select.From);
            var joinColumns = JoinColumnGatherer.Gather(aliases, select).ToList();

            if (joinColumns.Count > 0)
            {
                foreach (var jc in joinColumns)
                {
                    foreach (var col in select.Columns)
                    {
                        if (jc.Equals(col.Expression))
                        {
                            return(jc);
                        }
                    }
                }

                return(joinColumns[0]);
            }

            return(Expression.Constant(1, typeof(int?)));
        }
示例#6
0
        private Expression MakeSubquery(Expression expression)
        {
            var newAlias = new TableAlias();
            var aliases  = DbDeclaredAliasGatherer.Gather(expression);
            var decls    = new List <DbColumnDeclaration>();

            foreach (var ta in aliases)
            {
                foreach (var col in this.columns[ta])
                {
                    var name = decls.GetAvailableColumnName(col.Name);

                    var decl = new DbColumnDeclaration(name, col, col.QueryType);

                    decls.Add(decl);

                    var newCol = new DbColumnExpression(col.Type, col.QueryType, newAlias, col.Name);

                    this.map.Add(col, newCol);
                }
            }

            return(new DbSelectExpression(newAlias, decls, expression, null));
        }
        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;
            }
        }