public virtual void AddLimit(int limit)
        {
            if (_limit != null)
            {
                var subquery = new SelectExpression();

                var columnAliasCounter = 0;

                foreach (var columnExpression in _projection)
                {
                    if (subquery._projection.FindIndex(ce => ce.Name == columnExpression.Name) != -1)
                    {
                        columnExpression.Alias = "c" + columnAliasCounter++;
                    }

                    subquery._projection.Add(columnExpression);
                }

                subquery.AddTables(_tables);
                subquery.AddToOrderBy(_orderBy);

                subquery._limit = _limit;

                _tables.Clear();
                _projection.Clear();

                ClearOrderBy();

                _projectStar = true;
                _subquery    = subquery;
            }

            _limit = limit;
        }
Beispiel #2
0
        private void PushDownSubquery()
        {
            var subquery = new SelectExpression();

            var columnAliasCounter = 0;

            foreach (var columnExpression in _projection)
            {
                if (subquery._projection.FindIndex(ce => ce.Name == columnExpression.Name) != -1)
                {
                    columnExpression.Alias = "c" + columnAliasCounter++;
                }

                subquery._projection.Add(columnExpression);
            }

            subquery.AddTables(_tables);
            subquery.AddToOrderBy(_orderBy);

            subquery._limit       = _limit;
            subquery._isDistinct  = _isDistinct;
            subquery._subquery    = _subquery;
            subquery._projectStar = _projectStar;

            _limit      = null;
            _isDistinct = false;

            ClearTables();
            ClearProjection();
            ClearOrderBy();

            _projectStar = true;
            _subquery    = subquery;
        }
        private SelectExpression PushDownSubquery()
        {
            _subqueryDepth
                = _subqueryDepth != null
                    ? _subqueryDepth + 1
                    : 0;

            var subquery
                = new SelectExpression("t" + _subqueryDepth);

            var columnAliasCounter = 0;

            foreach (var aliasExpression in _projection.OfType <AliasExpression>())
            {
                var columnExpression = ((Expression)aliasExpression).TryGetColumnExpression();
                if (columnExpression != null &&
                    subquery._projection.OfType <AliasExpression>().Any(ae =>
                                                                        ae.TryGetColumnExpression()?.Name == columnExpression.Name))
                {
                    aliasExpression.Alias = "c" + columnAliasCounter++;
                }

                subquery._projection.Add(aliasExpression);
            }

            subquery.AddTables(_tables);
            subquery.AddToOrderBy(_orderBy);

            subquery._limit         = _limit;
            subquery._offset        = _offset;
            subquery._isDistinct    = _isDistinct;
            subquery._subqueryDepth = _subqueryDepth;
            subquery._projectStar   = _projectStar;

            _limit      = null;
            _offset     = null;
            _isDistinct = false;

            ClearTables();
            ClearProjection();
            ClearOrderBy();

            _projectStar = true;

            AddTable(subquery);

            return(subquery);
        }
Beispiel #4
0
        private SelectExpression PushDownSubquery()
        {
            _subqueryDepth
                = _subqueryDepth != null
                    ? _subqueryDepth + 1
                    : 0;

            var subquery
                = new SelectExpression("t" + _subqueryDepth);

            var columnAliasCounter = 0;

            foreach (var columnExpression in _projection)
            {
                if (subquery._projection.FindIndex(ce => ce.Name == columnExpression.Name) != -1)
                {
                    columnExpression.Alias = "c" + columnAliasCounter++;
                }

                subquery._projection.Add(columnExpression);
            }

            subquery.AddTables(_tables);
            subquery.AddToOrderBy(_orderBy);

            subquery._limit         = _limit;
            subquery._offset        = _offset;
            subquery._isDistinct    = _isDistinct;
            subquery._subqueryDepth = _subqueryDepth;
            subquery._projectStar   = _projectStar;

            _limit      = null;
            _offset     = null;
            _isDistinct = false;

            ClearTables();
            ClearProjection();
            ClearOrderBy();

            _projectStar = true;

            AddTable(subquery);

            return(subquery);
        }
        public virtual SelectExpression Clone([NotNull] string alias)
        {
            Check.NotEmpty(alias, nameof(alias));

            var selectExpression
                = new SelectExpression(alias)
                    {
                        _limit = _limit,
                        _offset = _offset,
                        _isDistinct = _isDistinct,
                        _subqueryDepth = _subqueryDepth,
                        _projectStar = _projectStar,
                        Predicate = Predicate
                    };

            selectExpression._projection.AddRange(_projection);

            selectExpression.AddTables(_tables);
            selectExpression.AddToOrderBy(_orderBy);

            return selectExpression;
        }
        public virtual SelectExpression Clone([NotNull] string alias)
        {
            Check.NotEmpty(alias, "alias");

            var selectExpression
                = new SelectExpression(alias)
                {
                _limit         = _limit,
                _offset        = _offset,
                _isDistinct    = _isDistinct,
                _subqueryDepth = _subqueryDepth,
                _projectStar   = _projectStar,
                Predicate      = Predicate
                };

            selectExpression._projection.AddRange(_projection);

            selectExpression.AddTables(_tables);
            selectExpression.AddToOrderBy(_orderBy);

            return(selectExpression);
        }
        private SelectExpression PushDownSubquery()
        {
            _subqueryDepth
                = _subqueryDepth != null
                    ? _subqueryDepth + 1
                    : 0;

            var subquery
                = new SelectExpression("t" + _subqueryDepth);

            var columnAliasCounter = 0;

            foreach (var aliasExpression in _projection.OfType<AliasExpression>())
            {
                var columnExpression = ((Expression)aliasExpression).TryGetColumnExpression();
                if (columnExpression != null
                    && subquery._projection.OfType<AliasExpression>().Any(ae =>
                        ae.TryGetColumnExpression()?.Name == columnExpression.Name))
                {
                    aliasExpression.Alias = "c" + columnAliasCounter++;
                }

                subquery._projection.Add(aliasExpression);
            }

            subquery.AddTables(_tables);
            subquery.AddToOrderBy(_orderBy);

            subquery._limit = _limit;
            subquery._offset = _offset;
            subquery._isDistinct = _isDistinct;
            subquery._subqueryDepth = _subqueryDepth;
            subquery._projectStar = _projectStar;

            _limit = null;
            _offset = null;
            _isDistinct = false;

            ClearTables();
            ClearProjection();
            ClearOrderBy();

            _projectStar = true;

            AddTable(subquery);

            return subquery;
        }
        private void PushDownSubquery()
        {
            var subquery = new SelectExpression();

            var columnAliasCounter = 0;

            foreach (var columnExpression in _projection)
            {
                if (subquery._projection.FindIndex(ce => ce.Name == columnExpression.Name) != -1)
                {
                    columnExpression.Alias = "c" + columnAliasCounter++;
                }

                subquery._projection.Add(columnExpression);
            }
            
            subquery.AddTables(_tables);
            subquery.AddToOrderBy(_orderBy);

            subquery._limit = _limit;
            subquery._isDistinct = _isDistinct;
            subquery._subquery = _subquery;
            subquery._projectStar = _projectStar;

            _limit = null;
            _isDistinct = false;

            ClearTables();
            ClearProjection();
            ClearOrderBy();

            _projectStar = true;
            _subquery = subquery;
        }
        private IEnumerable<Expression> CreateIncludeRelatedValuesStrategyFactories(
            IQuerySource querySource,
            IEnumerable<INavigation> navigationPath)
        {
            var selectExpression
                = _queryCompilationContext.FindSelectExpression(querySource);

            var targetTableExpression
                = selectExpression.FindTableForQuerySource(querySource);

            var readerIndex = 0;
            var canProduceInnerJoin = true;

            foreach (var navigation in navigationPath)
            {
                var targetEntityType = navigation.GetTargetType();
                var targetTableName = _queryCompilationContext.GetTableName(targetEntityType);
                var targetTableAlias = targetTableName.First().ToString().ToLower();

                if (!navigation.IsCollection())
                {
                    var joinedTableExpression
                        = new TableExpression(
                            targetTableName,
                            _queryCompilationContext.GetSchema(targetEntityType),
                            targetTableAlias,
                            querySource);

                    var readerOffset = selectExpression.Projection.Count;

                    canProduceInnerJoin
                        = canProduceInnerJoin
                          && (navigation.ForeignKey.IsRequired
                              && navigation.PointsToPrincipal);

                    var joinExpression
                        = canProduceInnerJoin
                            ? selectExpression
                                .AddInnerJoin(joinedTableExpression)
                            : selectExpression
                                .AddOuterJoin(joinedTableExpression);

                    var materializer
                        = new MaterializerFactory(
                            _queryCompilationContext.EntityMaterializerSource)
                            .CreateMaterializer(
                                targetEntityType,
                                selectExpression,
                                projectionAdder:
                                    (p, se) => se.AddToProjection(
                                        new ColumnExpression(
                                            _queryCompilationContext.GetColumnName(p),
                                            p,
                                            joinedTableExpression)) - readerOffset,
                                querySource: null);

                    joinExpression.Predicate
                        = BuildJoinEqualityExpression(
                            navigation,
                            (navigation.PointsToPrincipal
                                ? targetEntityType
                                : navigation.EntityType)
                                .GetPrimaryKey().Properties,
                            navigation.PointsToPrincipal ? targetTableExpression : joinExpression,
                            navigation.PointsToPrincipal ? joinExpression : targetTableExpression);

                    targetTableExpression = joinedTableExpression;

                    yield return
                        Expression.Lambda(
                            Expression.Call(
                                _queryCompilationContext.QueryMethodProvider
                                    .CreateReferenceIncludeRelatedValuesStrategyMethod,
                                Expression.Convert(EntityQueryModelVisitor.QueryContextParameter, typeof(RelationalQueryContext)),
                                Expression.Constant(readerIndex),
                                Expression.Constant(readerOffset),
                                materializer));
                }
                else
                {
                    var principalTable
                        = selectExpression.Tables.Last(t => t.QuerySource == querySource);

                    foreach (var property in navigation.EntityType.GetPrimaryKey().Properties)
                    {
                        selectExpression
                            .AddToOrderBy(
                                _queryCompilationContext.GetColumnName(property),
                                property,
                                principalTable,
                                OrderingDirection.Asc);
                    }

                    var targetSelectExpression = new SelectExpression();

                    targetTableExpression
                        = new TableExpression(
                            targetTableName,
                            _queryCompilationContext.GetSchema(targetEntityType),
                            targetTableAlias,
                            querySource);

                    targetSelectExpression.AddTable(targetTableExpression);

                    var materializer
                        = new MaterializerFactory(
                            _queryCompilationContext.EntityMaterializerSource)
                            .CreateMaterializer(
                                targetEntityType,
                                targetSelectExpression,
                                (p, se) => se.AddToProjection(
                                    _queryCompilationContext.GetColumnName(p),
                                    p,
                                    querySource),
                                querySource: null);

                    var innerJoinSelectExpression
                        = selectExpression.Clone(
                            ((ColumnExpression)selectExpression.OrderBy.Last().Expression).TableAlias);

                    innerJoinSelectExpression.IsDistinct = true;
                    innerJoinSelectExpression.ClearProjection();

                    foreach (var columnExpression
                        in innerJoinSelectExpression.OrderBy
                            .Select(o => o.Expression)
                            .Cast<ColumnExpression>())
                    {
                        innerJoinSelectExpression.AddToProjection(columnExpression);
                    }

                    innerJoinSelectExpression.ClearOrderBy();

                    var primaryKeyProperties = navigation.EntityType.GetPrimaryKey().Properties;

                    var innerJoinExpression
                        = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression);

                    foreach (var ordering in selectExpression.OrderBy)
                    {
                        var columnExpression = (ColumnExpression)ordering.Expression;

                        targetSelectExpression
                            .AddToOrderBy(
                                columnExpression.Alias ?? columnExpression.Name,
                                columnExpression.Property,
                                innerJoinExpression,
                                ordering.OrderingDirection);
                    }

                    innerJoinExpression.Predicate
                        = BuildJoinEqualityExpression(
                            navigation,
                            primaryKeyProperties,
                            targetTableExpression,
                            innerJoinExpression);

                    var readerParameter = Expression.Parameter(typeof(DbDataReader));

                    selectExpression = targetSelectExpression;
                    readerIndex++;

                    yield return
                        Expression.Lambda(
                            Expression.Call(
                                _queryCompilationContext.QueryMethodProvider
                                    .CreateCollectionIncludeRelatedValuesStrategyMethod,
                                Expression.Call(
                                    _queryCompilationContext.QueryMethodProvider.QueryMethod
                                        .MakeGenericMethod(typeof(IValueReader)),
                                    EntityQueryModelVisitor.QueryContextParameter,
                                    Expression.Constant(new CommandBuilder(targetSelectExpression, _queryCompilationContext)),
                                    Expression.Lambda(
                                        Expression.Call(
                                            _createValueReaderForIncludeMethodInfo,
                                            EntityQueryModelVisitor.QueryContextParameter,
                                            readerParameter,
                                            Expression.Constant(targetEntityType)),
                                        readerParameter)),
                                materializer));
                }
            }
        }