Пример #1
0
        public InExpression(
            [NotNull] AliasExpression operand,
            [NotNull] SelectExpression subQuery)
        {
            Check.NotNull(operand, nameof(operand));
            Check.NotNull(subQuery, nameof(subQuery));

            Operand  = operand;
            SubQuery = subQuery;
        }
Пример #2
0
        public InExpression(
            [NotNull] AliasExpression operand,
            [NotNull] IReadOnlyList <Expression> values)
        {
            Check.NotNull(operand, nameof(operand));
            Check.NotNull(values, nameof(values));

            Operand = operand;
            Values  = values;
        }
Пример #3
0
        public virtual SelectExpression PushDownSubquery()
        {
            _subqueryDepth++;

            var subquery = new SelectExpression(_sqlQueryGeneratorFactory, SystemAliasPrefix + _subqueryDepth);

            var columnAliasCounter = 0;

            foreach (var expression in _projection)
            {
                var aliasExpression = expression as AliasExpression;

                if (aliasExpression != null)
                {
                    var columnExpression = aliasExpression.TryGetColumnExpression();

                    if (columnExpression != null &&
                        subquery._projection.OfType <AliasExpression>()
                        .Any(ae => ae.TryGetColumnExpression()?.Name == columnExpression.Name))
                    {
                        aliasExpression.Alias = "c" + columnAliasCounter++;
                    }
                }
                else
                {
                    aliasExpression = new AliasExpression("c" + columnAliasCounter++, expression);
                }

                subquery._projection.Add(aliasExpression);
            }

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

            subquery._limit         = _limit;
            subquery._offset        = _offset;
            subquery._isDistinct    = _isDistinct;
            subquery._subqueryDepth = _subqueryDepth;
            subquery.IsProjectStar  = IsProjectStar || !subquery._projection.Any();

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

            Predicate = null;
            ClearTables();
            ClearProjection();
            ClearOrderBy();

            AddTable(subquery);

            return(subquery);
        }
Пример #4
0
        // TODO: Make polymorphic
        public virtual Expression UpdateColumnExpression(
            [NotNull] Expression expression,
            [NotNull] TableExpressionBase tableExpression)
        {
            Check.NotNull(expression, nameof(expression));
            Check.NotNull(tableExpression, nameof(tableExpression));

            var aliasExpression  = expression as AliasExpression;
            var columnExpression = expression as ColumnExpression;

            if (columnExpression != null)
            {
                return(new ColumnExpression(columnExpression.Name, columnExpression.Property, tableExpression));
            }

            if (aliasExpression != null)
            {
                var newAliasExpression
                    = new AliasExpression(
                          aliasExpression.Alias,
                          UpdateColumnExpression(aliasExpression.Expression, tableExpression))
                    {
                    SourceMember = aliasExpression.SourceMember
                    };

                return(newAliasExpression);
            }

            switch (expression.NodeType)
            {
            case ExpressionType.Coalesce:
            {
                var binaryExpression = (BinaryExpression)expression;
                var left             = UpdateColumnExpression(binaryExpression.Left, tableExpression);
                var right            = UpdateColumnExpression(binaryExpression.Right, tableExpression);
                return(binaryExpression.Update(left, binaryExpression.Conversion, right));
            }

            case ExpressionType.Conditional:
            {
                var conditionalExpression = (ConditionalExpression)expression;
                var test    = UpdateColumnExpression(conditionalExpression.Test, tableExpression);
                var ifTrue  = UpdateColumnExpression(conditionalExpression.IfTrue, tableExpression);
                var ifFalse = UpdateColumnExpression(conditionalExpression.IfFalse, tableExpression);
                return(conditionalExpression.Update(test, ifTrue, ifFalse));
            }
            }

            return(expression);
        }
Пример #5
0
        public virtual AliasExpression AddToOrderBy(
            [NotNull] string column,
            [NotNull] IProperty property,
            [NotNull] TableExpressionBase table,
            OrderingDirection orderingDirection)
        {
            Check.NotEmpty(column, nameof(column));
            Check.NotNull(property, nameof(property));
            Check.NotNull(table, nameof(table));

            var columnExpression = new ColumnExpression(column, property, table);
            var aliasExpression  = new AliasExpression(columnExpression);

            if (_orderBy.FindIndex(o => o.Expression.TryGetColumnExpression()?.Equals(columnExpression) ?? false) == -1)
            {
                _orderBy.Add(new Ordering(aliasExpression, orderingDirection));
            }

            return(aliasExpression);
        }
Пример #6
0
        public virtual int AddToProjection([NotNull] ColumnExpression columnExpression)
        {
            Check.NotNull(columnExpression, nameof(columnExpression));

            var projectionIndex
                = _projection
                  .FindIndex(e =>
            {
                var ce = e.TryGetColumnExpression();

                return(ce?.Property == columnExpression.Property &&
                       ce?.Type == columnExpression.Type &&
                       ce?.TableAlias == columnExpression.TableAlias);
            });

            if (projectionIndex == -1)
            {
                var aliasExpression = new AliasExpression(columnExpression);

                if (Alias != null)
                {
                    var currentAlias = columnExpression.Name;
                    var uniqueAlias  = CreateUniqueProjectionAlias(currentAlias);

                    if (!string.Equals(currentAlias, uniqueAlias, StringComparison.OrdinalIgnoreCase))
                    {
                        aliasExpression.Alias = uniqueAlias;
                    }
                }

                projectionIndex = _projection.Count;

                _projection.Add(aliasExpression);

                IsProjectStar = false;
            }

            return(projectionIndex);
        }
Пример #7
0
        public virtual void AddToOrderBy([NotNull] IEnumerable <Ordering> orderings)
        {
            Check.NotNull(orderings, nameof(orderings));

            foreach (var ordering in orderings)
            {
                var aliasExpression  = ordering.Expression as AliasExpression;
                var columnExpression = ordering.Expression as ColumnExpression;

                if (aliasExpression != null)
                {
                    var newAlias = new AliasExpression(aliasExpression.Alias, aliasExpression.Expression);
                    _orderBy.Add(new Ordering(newAlias, ordering.OrderingDirection));
                }
                else if (columnExpression != null)
                {
                    _orderBy.Add(new Ordering(new AliasExpression(columnExpression), ordering.OrderingDirection));
                }
                else
                {
                    _orderBy.Add(ordering);
                }
            }
        }
Пример #8
0
        // TODO: Make polymorphic
        public virtual Expression UpdateColumnExpression(
            [NotNull] Expression expression,
            [NotNull] TableExpressionBase tableExpression)
        {
            Check.NotNull(expression, nameof(expression));
            Check.NotNull(tableExpression, nameof(tableExpression));

            var aliasExpression = expression as AliasExpression;
            var columnExpression = expression as ColumnExpression;

            if (columnExpression != null)
            {
                return new ColumnExpression(columnExpression.Name, columnExpression.Property, tableExpression);
            }

            if (aliasExpression != null)
            {
                var newAliasExpression
                    = new AliasExpression(
                        aliasExpression.Alias,
                        UpdateColumnExpression(aliasExpression.Expression, tableExpression))
                    {
                        SourceMember = aliasExpression.SourceMember
                    };

                return newAliasExpression;
            }

            switch (expression.NodeType)
            {
                case ExpressionType.Coalesce:
                {
                    var binaryExpression = (BinaryExpression)expression;
                    var left = UpdateColumnExpression(binaryExpression.Left, tableExpression);
                    var right = UpdateColumnExpression(binaryExpression.Right, tableExpression);
                    return binaryExpression.Update(left, binaryExpression.Conversion, right);
                }
                case ExpressionType.Conditional:
                {
                    var conditionalExpression = (ConditionalExpression)expression;
                    var test = UpdateColumnExpression(conditionalExpression.Test, tableExpression);
                    var ifTrue = UpdateColumnExpression(conditionalExpression.IfTrue, tableExpression);
                    var ifFalse = UpdateColumnExpression(conditionalExpression.IfFalse, tableExpression);
                    return conditionalExpression.Update(test, ifTrue, ifFalse);
                }
            }

            return expression;
        }
Пример #9
0
        public virtual void AddToOrderBy([NotNull] IEnumerable<Ordering> orderings)
        {
            Check.NotNull(orderings, nameof(orderings));

            foreach (var ordering in orderings)
            {
                var aliasExpression = ordering.Expression as AliasExpression;
                var columnExpression = ordering.Expression as ColumnExpression;

                if (aliasExpression != null)
                {
                    var newAlias = new AliasExpression(aliasExpression.Alias, aliasExpression.Expression);
                    _orderBy.Add(new Ordering(newAlias, ordering.OrderingDirection));
                }
                else if (columnExpression != null)
                {
                    _orderBy.Add(new Ordering(new AliasExpression(columnExpression), ordering.OrderingDirection));
                }
                else
                {
                    _orderBy.Add(ordering);
                }
            }
        }
Пример #10
0
        public virtual AliasExpression AddToOrderBy(
            [NotNull] string column,
            [NotNull] IProperty property,
            [NotNull] TableExpressionBase table,
            OrderingDirection orderingDirection)
        {
            Check.NotEmpty(column, nameof(column));
            Check.NotNull(property, nameof(property));
            Check.NotNull(table, nameof(table));

            var columnExpression = new ColumnExpression(column, property, table);
            var aliasExpression = new AliasExpression(columnExpression);

            if (_orderBy.FindIndex(o => o.Expression.TryGetColumnExpression()?.Equals(columnExpression) ?? false) == -1)
            {
                _orderBy.Add(new Ordering(aliasExpression, orderingDirection));
            }

            return aliasExpression;
        }
Пример #11
0
        public virtual int AddToProjection([NotNull] ColumnExpression columnExpression)
        {
            Check.NotNull(columnExpression, nameof(columnExpression));

            var projectionIndex
                = _projection
                    .FindIndex(e =>
                        {
                            var ce = e.TryGetColumnExpression();

                            return ce?.Property == columnExpression.Property
                                   && ce?.Type == columnExpression.Type
                                   && ce.TableAlias == columnExpression.TableAlias;
                        });

            if (projectionIndex == -1)
            {
                var aliasExpression = new AliasExpression(columnExpression);

                if (Alias != null)
                {
                    var currentAlias = columnExpression.Name;
                    var uniqueAlias = CreateUniqueProjectionAlias(currentAlias);

                    if (!string.Equals(currentAlias, uniqueAlias, StringComparison.OrdinalIgnoreCase))
                    {
                        aliasExpression.Alias = uniqueAlias;
                    }
                }

                projectionIndex = _projection.Count;

                _projection.Add(aliasExpression);

                IsProjectStar = false;
            }

            return projectionIndex;
        }
Пример #12
0
        public virtual SelectExpression PushDownSubquery()
        {
            _subqueryDepth++;

            var subquery = new SelectExpression(_sqlQueryGeneratorFactory, SystemAliasPrefix + _subqueryDepth);

            var columnAliasCounter = 0;

            foreach (var expression in _projection)
            {
                var aliasExpression = expression as AliasExpression;

                if (aliasExpression != null)
                {
                    var columnExpression = aliasExpression.TryGetColumnExpression();

                    if (columnExpression != null
                        && subquery._projection.OfType<AliasExpression>()
                            .Any(ae => ae.TryGetColumnExpression()?.Name == columnExpression.Name))
                    {
                        aliasExpression.Alias = "c" + columnAliasCounter++;
                    }
                }
                else
                {
                    aliasExpression = new AliasExpression("c" + columnAliasCounter++, expression);
                }

                subquery._projection.Add(aliasExpression);
            }

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

            subquery._limit = _limit;
            subquery._offset = _offset;
            subquery._isDistinct = _isDistinct;
            subquery._subqueryDepth = _subqueryDepth;
            subquery.IsProjectStar = IsProjectStar || !subquery._projection.Any();

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

            Predicate = null;
            ClearTables();
            ClearProjection();
            ClearOrderBy();

            AddTable(subquery);

            return subquery;
        }
Пример #13
0
 private bool Equals(AliasExpression other)
 => Equals(_expression, other._expression) &&
 string.Equals(_alias, other._alias);
Пример #14
0
 public virtual int AddToProjection([NotNull] AliasExpression aliasExpression)
 => AddAliasToProjection(aliasExpression.Alias, aliasExpression.Expression);
            private Expression VisitSelectExpression(SelectExpression selectExpression)
            {
                base.Visit(selectExpression);

                if (!RequiresRowNumberPaging(selectExpression))
                {
                    return selectExpression;
                }

                var subQuery = selectExpression.PushDownSubquery();

                foreach (var projection in subQuery.Projection)
                {
                    var alias = projection as AliasExpression;
                    var column = projection as ColumnExpression;

                    if (column != null)
                    {
                        column = new ColumnExpression(column.Name, column.Property, subQuery);
                        selectExpression.AddToProjection(column);
                        continue;
                    }

                    column = alias?.TryGetColumnExpression();

                    if (column != null)
                    {
                        column = new ColumnExpression(column.Name, column.Property, subQuery);
                        alias = new AliasExpression(alias.Alias, column);
                        selectExpression.AddToProjection(alias);
                    }
                    else
                    {
                        column = new ColumnExpression(alias.Alias, alias.Expression.Type, subQuery);
                        selectExpression.AddToProjection(column);
                    }
                }

                if (subQuery.OrderBy.Count == 0)
                {
                    subQuery.AddToOrderBy(
                        new Ordering(new SqlFunctionExpression("@@RowCount", typeof(int)), OrderingDirection.Asc));
                }

                var columnExpression = new ColumnExpression(RowNumberColumnName, typeof(int), subQuery);
                var rowNumber = new RowNumberExpression(columnExpression, subQuery.OrderBy);

                subQuery.ClearOrderBy();
                subQuery.AddToProjection(rowNumber, false);

                Expression predicate = null;

                var offset = subQuery.Offset ?? 0;

                if (subQuery.Offset.HasValue)
                {
                    predicate = Expression.GreaterThan(columnExpression, Expression.Constant(offset));
                }

                if (subQuery.Limit.HasValue)
                {
                    var exp = Expression.LessThanOrEqual(columnExpression, Expression.Constant(offset + subQuery.Limit.Value));
                    if (predicate != null)
                    {
                        exp = Expression.AndAlso(predicate, exp);
                    }
                    predicate = exp;
                }

                selectExpression.Predicate = predicate;

                return selectExpression;
            }
Пример #16
0
 public virtual int AddToProjection([NotNull] AliasExpression aliasExpression)
 {
     return(AddAliasToProjection(aliasExpression.Alias, aliasExpression.Expression));
 }