예제 #1
0
 private InnerJoinExpression(
     TableExpressionBase table,
     SqlExpression joinPredicate,
     IEnumerable <IAnnotation>?annotations)
     : base(table, joinPredicate, annotations)
 {
 }
        private Expression BuildColumnExpression(
            IReadOnlyCollection <Expression> projections,
            TableExpressionBase tableExpression,
            IProperty property)
        {
            Check.NotNull(property, nameof(property));

            if (projections.Count == 0)
            {
                return(new ColumnExpression(
                           _queryCompilationContext.GetColumnName(property),
                           property,
                           tableExpression));
            }

            var matchingColumnExpression
                = projections
                  .OfType <AliasExpression>()
                  .Last(p => p.TryGetColumnExpression()?.Property == property);

            return(new ColumnExpression(
                       matchingColumnExpression.Alias ?? matchingColumnExpression.TryGetColumnExpression().Name,
                       property,
                       tableExpression));
        }
예제 #3
0
 internal ColumnExpression(ProjectionExpression subqueryProjection, TableExpressionBase table)
     : this(
         subqueryProjection.Alias, table,
         subqueryProjection.Type, subqueryProjection.Expression.TypeMapping,
         IsNullableProjection(subqueryProjection))
 {
 }
        private static void LiftOrderBy(
            SelectExpression innerJoinSelectExpression,
            SelectExpression targetSelectExpression,
            TableExpressionBase innerJoinExpression)
        {
            var needOrderingChanges
                = innerJoinSelectExpression.OrderBy
                  .Any(x => x.Expression is SelectExpression ||
                       x.Expression.IsAliasWithColumnExpression() ||
                       x.Expression.IsAliasWithSelectExpression());

            var orderings = innerJoinSelectExpression.OrderBy.ToList();

            if (needOrderingChanges)
            {
                innerJoinSelectExpression.ClearOrderBy();
            }

            foreach (var ordering in orderings)
            {
                var orderingExpression = ordering.Expression;

                var aliasExpression = ordering.Expression as AliasExpression;

                if (aliasExpression?.Alias != null)
                {
                    var columnExpression = aliasExpression.TryGetColumnExpression();
                    if (columnExpression != null)
                    {
                        orderingExpression
                            = new ColumnExpression(
                                  aliasExpression.Alias,
                                  columnExpression.Property,
                                  columnExpression.Table);
                    }
                }

                var index = orderingExpression is SelectExpression
                    ? innerJoinSelectExpression.AddAliasToProjection(innerJoinSelectExpression.Alias + "_" + innerJoinSelectExpression.Projection.Count, orderingExpression)
                    : innerJoinSelectExpression.AddToProjection(orderingExpression);

                var expression = innerJoinSelectExpression.Projection[index];

                if (needOrderingChanges)
                {
                    innerJoinSelectExpression.AddToOrderBy(new Ordering(expression.TryGetColumnExpression() ?? expression, ordering.OrderingDirection));
                }

                var newExpression
                    = targetSelectExpression.UpdateColumnExpression(expression, innerJoinExpression);

                targetSelectExpression.AddToOrderBy(new Ordering(newExpression, ordering.OrderingDirection));
            }

            if ((innerJoinSelectExpression.Limit == null) &&
                (innerJoinSelectExpression.Offset == null))
            {
                innerJoinSelectExpression.ClearOrderBy();
            }
        }
        private Expression TryParseExpression(TableExpressionBase table, IEntityType entityType, ICollection <Expression> expressions)
        {
            var expression = expressions.First();
            var visitor    = new PrivateParseExpressionVisitor(table, entityType);

            return(visitor.Visit(expression));
        }
예제 #6
0
        private Expression BuildColumnExpression(
            IReadOnlyCollection <Expression> projections,
            TableExpressionBase tableExpression,
            IProperty property,
            IQuerySource querySource)
        {
            Check.NotNull(property, nameof(property));

            if (projections.Count == 0)
            {
                return(new ColumnExpression(
                           _relationalAnnotationProvider.For(property).ColumnName,
                           property,
                           tableExpression));
            }

            var aliasExpressions
                = projections
                  .OfType <AliasExpression>()
                  .Where(p => p.TryGetColumnExpression()?.Property == property)
                  .ToList();

            var aliasExpression
                = aliasExpressions.Count == 1
                    ? aliasExpressions[0]
                    : aliasExpressions.Last(ae => ae.TryGetColumnExpression().Table.QuerySource == querySource);

            return(new ColumnExpression(
                       aliasExpression.Alias ?? aliasExpression.TryGetColumnExpression().Name,
                       property,
                       tableExpression));
        }
 /// <summary>
 ///     Creates a new instance of the <see cref="PredicateJoinExpressionBase" /> class.
 /// </summary>
 /// <param name="table">A table source to join with.</param>
 /// <param name="joinPredicate">A predicate to use for the join.</param>
 /// <param name="annotations">A collection of annotations associated with this expression.</param>
 protected PredicateJoinExpressionBase(
     TableExpressionBase table,
     SqlExpression joinPredicate,
     IEnumerable <IAnnotation>?annotations)
     : base(table, annotations)
 {
     JoinPredicate = joinPredicate;
 }
        public EntityProjectionExpression([NotNull] IEntityType entityType, [NotNull] TableExpressionBase innerTable, bool nullable)
        {
            Check.NotNull(entityType, nameof(entityType));
            Check.NotNull(innerTable, nameof(innerTable));

            EntityType  = entityType;
            _innerTable = innerTable;
            _nullable   = nullable;
        }
        protected override TableExpressionBase Visit(TableExpressionBase tableExpressionBase)
        {
            if (tableExpressionBase is TemporalTableExpression)
            {
                return(tableExpressionBase);
            }

            return(base.Visit(tableExpressionBase));
        }
        protected override TableExpressionBase Visit([NotNull] TableExpressionBase tableExpressionBase)
        {
            switch (tableExpressionBase)
            {
            case SingleRowTableExpression singleRowTableExpression:
                return(singleRowTableExpression);

            default:
                return(base.Visit(tableExpressionBase));
            }
        }
예제 #11
0
        private Expression BuildJoinEqualityExpression(
            INavigation navigation,
            TableExpressionBase targetTableExpression,
            TableExpressionBase joinExpression,
            IQuerySource querySource)
        {
            Expression joinPredicateExpression = null;

            var targetTableProjections = ExtractProjections(targetTableExpression).ToList();
            var joinTableProjections   = ExtractProjections(joinExpression).ToList();

            for (var i = 0; i < navigation.ForeignKey.Properties.Count; i++)
            {
                var principalKeyProperty = navigation.ForeignKey.PrincipalKey.Properties[i];
                var foreignKeyProperty   = navigation.ForeignKey.Properties[i];

                var foreignKeyColumnExpression
                    = BuildColumnExpression(
                          targetTableProjections, targetTableExpression, foreignKeyProperty, querySource);

                var primaryKeyColumnExpression
                    = BuildColumnExpression(
                          joinTableProjections, joinExpression, principalKeyProperty, querySource);

                var primaryKeyExpression = primaryKeyColumnExpression;

                if (foreignKeyColumnExpression.Type != primaryKeyExpression.Type)
                {
                    if (foreignKeyColumnExpression.Type.IsNullableType() &&
                        !primaryKeyExpression.Type.IsNullableType())
                    {
                        primaryKeyExpression
                            = Expression.Convert(primaryKeyExpression, foreignKeyColumnExpression.Type);
                    }
                    else if (primaryKeyExpression.Type.IsNullableType() &&
                             !foreignKeyColumnExpression.Type.IsNullableType())
                    {
                        foreignKeyColumnExpression
                            = Expression.Convert(foreignKeyColumnExpression, primaryKeyColumnExpression.Type);
                    }
                }

                var equalExpression
                    = Expression.Equal(foreignKeyColumnExpression, primaryKeyExpression);

                joinPredicateExpression
                    = joinPredicateExpression == null
                        ? equalExpression
                        : Expression.AndAlso(joinPredicateExpression, equalExpression);
            }

            return(joinPredicateExpression);
        }
예제 #12
0
        private static IEnumerable <Expression> ExtractProjections(TableExpressionBase tableExpression)
        {
            var selectExpression = tableExpression as SelectExpression;

            if (selectExpression != null)
            {
                return(selectExpression.Projection.ToList());
            }

            var joinExpression = tableExpression as JoinExpressionBase;

            return(joinExpression != null
                ? ExtractProjections(joinExpression.TableExpression)
                : Enumerable.Empty <Expression>());
        }
예제 #13
0
 public override void AddTable(TableExpressionBase tableExpression)
 {
     if (UseAsOf && tableExpression is TableExpression te)
     {
         base.AddTable(new AsOfTableExpression(AsOf, te.Table, te.Schema, te.Alias, te.QuerySource));
     }
     else if (UseBetween && tableExpression is TableExpression tableExpr)
     {
         base.AddTable(new BetweenTableExpression(StartTime, EndTime, tableExpr.Table, tableExpr.Schema, tableExpr.Alias, tableExpr.QuerySource));
     }
     else
     {
         base.AddTable(tableExpression);
     }
 }
예제 #14
0
        private Expression BuildJoinEqualityExpression(
            INavigation navigation,
            IReadOnlyList <IProperty> primaryKeyProperties,
            TableExpressionBase targetTableExpression,
            TableExpressionBase joinExpression)
        {
            Expression joinPredicateExpression = null;

            for (var i = 0; i < navigation.ForeignKey.Properties.Count; i++)
            {
                var primaryKeyProperty = primaryKeyProperties[i];
                var foreignKeyProperty = navigation.ForeignKey.Properties[i];

                var foreignKeyColumnExpression
                    = new ColumnExpression(
                          QueryCompilationContext.GetColumnName(foreignKeyProperty),
                          foreignKeyProperty,
                          targetTableExpression);

                Expression primaryKeyColumnExpression
                    = new ColumnExpression(
                          QueryCompilationContext.GetColumnName(primaryKeyProperty),
                          primaryKeyProperty,
                          joinExpression);

                if (foreignKeyColumnExpression.Type != primaryKeyColumnExpression.Type)
                {
                    if (foreignKeyColumnExpression.Type.IsNullableType() &&
                        !primaryKeyColumnExpression.Type.IsNullableType())
                    {
                        primaryKeyColumnExpression
                            = Expression.Convert(primaryKeyColumnExpression, foreignKeyColumnExpression.Type);
                    }
                }

                var equalExpression
                    = Expression.Equal(foreignKeyColumnExpression, primaryKeyColumnExpression);

                joinPredicateExpression
                    = joinPredicateExpression == null
                        ? equalExpression
                        : Expression.AndAlso(joinPredicateExpression, equalExpression);
            }

            return(joinPredicateExpression);
        }
예제 #15
0
        private static void LiftOrderBy(
            SelectExpression innerJoinSelectExpression,
            SelectExpression targetSelectExpression,
            TableExpressionBase innerJoinExpression)
        {
            foreach (var ordering in innerJoinSelectExpression.OrderBy)
            {
                var orderingExpression = ordering.Expression;

                var aliasExpression = ordering.Expression as AliasExpression;

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

                    if (columnExpression != null)
                    {
                        orderingExpression
                            = new ColumnExpression(
                                  aliasExpression.Alias,
                                  columnExpression.Property,
                                  columnExpression.Table);
                    }
                }

                var index = innerJoinSelectExpression.AddToProjection(orderingExpression);

                var expression = innerJoinSelectExpression.Projection[index];

                var newExpression
                    = targetSelectExpression.UpdateColumnExpression(expression, innerJoinExpression);

                targetSelectExpression.AddToOrderBy(new Ordering(newExpression, ordering.OrderingDirection));
            }

            if (innerJoinSelectExpression.Limit == null &&
                innerJoinSelectExpression.Offset == null)
            {
                innerJoinSelectExpression.ClearOrderBy();
            }
        }
예제 #16
0
 //from ef core
 private static bool IsNonComposedSetOperation(SelectExpression selectExpression)
 {
     if (selectExpression.Offset == null && selectExpression.Limit == null && !selectExpression.IsDistinct && selectExpression.Predicate == null && selectExpression.Having == null && selectExpression.Orderings.Count == 0 && selectExpression.GroupBy.Count == 0 && selectExpression.Tables.Count == 1)
     {
         TableExpressionBase tableExpressionBase = selectExpression.Tables[0];
         SetOperationBase    setOperation        = tableExpressionBase as SetOperationBase;
         if (setOperation != null && selectExpression.Projection.Count == setOperation.Source1.Projection.Count)
         {
             return(selectExpression.Projection.Select(delegate(ProjectionExpression pe, int index)
             {
                 ColumnExpression columnExpression = pe.Expression as ColumnExpression;
                 if (columnExpression != null && string.Equals(columnExpression.Table.Alias, setOperation.Alias, StringComparison.OrdinalIgnoreCase))
                 {
                     return string.Equals(columnExpression.Name, setOperation.Source1.Projection[index].Alias, StringComparison.OrdinalIgnoreCase);
                 }
                 return false;
             }).All((bool e) => e));
         }
     }
     return(false);
 }
예제 #17
0
        private Expression BuildColumnExpression(
            IReadOnlyCollection <ColumnExpression> projections,
            TableExpressionBase tableExpression,
            IProperty property)
        {
            if (projections.Count == 0)
            {
                return(new ColumnExpression(
                           _queryCompilationContext.GetColumnName(property),
                           property,
                           tableExpression));
            }

            var matchingColumnExpression
                = projections.Single(p => p.Property == property);

            return(new ColumnExpression(
                       matchingColumnExpression.Alias ?? matchingColumnExpression.Name,
                       property,
                       tableExpression));
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        // Issue#11266 This method is being used by provider code. Do not break.
        public static ColumnReferenceExpression LiftExpressionFromSubquery(
            [NotNull] this Expression expression,
            [NotNull] TableExpressionBase table)
        {
            Check.NotNull(expression, nameof(expression));
            Check.NotNull(table, nameof(table));

            switch (expression)
            {
            case ColumnExpression columnExpression:
                return(new ColumnReferenceExpression(columnExpression, table));

            case AliasExpression aliasExpression:
                return(new ColumnReferenceExpression(aliasExpression, table));

            case ColumnReferenceExpression columnReferenceExpression:
                return(new ColumnReferenceExpression(columnReferenceExpression, table));
            }

            Debug.Fail("LiftExpressionFromSubquery was called on incorrect expression type.");

            return(null);
        }
예제 #19
0
    private List <TableExpressionBase> ExtractTableExpressions(TableExpressionBase tableExpressionBase)
    {
        if (tableExpressionBase is JoinExpressionBase joinExpression)
        {
            tableExpressionBase = joinExpression.Table;
        }

        if (tableExpressionBase is TableExpression tableExpression)
        {
            return(new List <TableExpressionBase> {
                tableExpression
            });
        }

        if (tableExpressionBase is SelectExpression selectExpression)
        {
            var result = new List <TableExpressionBase>();
            foreach (var table in selectExpression.Tables)
            {
                result.AddRange(ExtractTableExpressions(table));
            }

            return(result);
        }

        if (tableExpressionBase is SetOperationBase setOperationBase)
        {
            var result = new List <TableExpressionBase>();
            result.AddRange(ExtractTableExpressions(setOperationBase.Source1));
            result.AddRange(ExtractTableExpressions(setOperationBase.Source2));

            return(result);
        }

        throw new InvalidOperationException("Unsupported table expression base type.");
    }
예제 #20
0
 protected JoinExpressionBase(TableExpressionBase table)
     : base("")
 {
     Table = table;
 }
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 protected override TableExpressionBase Visit(TableExpressionBase tableExpressionBase)
 {
     return(tableExpressionBase is TemporalTableExpression temporalTableExpression
         ? temporalTableExpression
         : base.Visit(tableExpressionBase));
 }
예제 #22
0
 /// <summary>
 ///     Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will
 ///     return this expression.
 /// </summary>
 /// <param name="table">The <see cref="JoinExpressionBase.Table" /> property of the result.</param>
 /// <param name="joinPredicate">The <see cref="PredicateJoinExpressionBase.JoinPredicate" /> property of the result.</param>
 /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
 public virtual InnerJoinExpression Update(TableExpressionBase table, SqlExpression joinPredicate)
 => table != Table || joinPredicate != JoinPredicate
         ? new InnerJoinExpression(table, joinPredicate, GetAnnotations())
         : this;
 public EntityProjectionExpression(IEntityType entityType, TableExpressionBase innerTable, bool nullable)
 {
     EntityType  = entityType;
     _innerTable = innerTable;
     _nullable   = nullable;
 }
예제 #24
0
 /// <summary>
 ///     Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will
 ///     return this expression.
 /// </summary>
 /// <param name="table">The <see cref="JoinExpressionBase.Table" /> property of the result.</param>
 /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
 public virtual OuterApplyExpression Update(TableExpressionBase table)
 => table != Table
         ? new OuterApplyExpression(table, GetAnnotations())
         : this;
예제 #25
0
 /// <summary>
 ///     Creates a new instance of the <see cref="OuterApplyExpression" /> class.
 /// </summary>
 /// <param name="table">A table source to OUTER APPLY with.</param>
 public OuterApplyExpression(TableExpressionBase table)
     : this(table, annotations : null)
 {
 }
예제 #26
0
 /// <summary>
 ///     Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will
 ///     return this expression.
 /// </summary>
 /// <param name="table">The <see cref="JoinExpressionBase.Table" /> property of the result.</param>
 /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
 public virtual CrossApplyExpression Update(TableExpressionBase table)
 => table != Table
         ? new CrossApplyExpression(table)
         : this;
예제 #27
0
 /// <summary>
 ///     Creates a new instance of the <see cref="CrossApplyExpression" /> class.
 /// </summary>
 /// <param name="table">A table source to CROSS APPLY with.</param>
 public CrossApplyExpression(TableExpressionBase table)
     : base(table)
 {
 }
예제 #28
0
 private OuterApplyExpression(TableExpressionBase table, IEnumerable <IAnnotation>?annotations)
     : base(table, annotations)
 {
 }
예제 #29
0
 /// <summary>
 ///     Creates a new instance of the <see cref="CrossJoinExpression" /> class.
 /// </summary>
 /// <param name="table">A table source to CROSS JOIN with.</param>
 public CrossJoinExpression(TableExpressionBase table)
     : base(table)
 {
 }
예제 #30
0
 public EntityProjectionExpression([NotNull] IEntityType entityType, [NotNull] TableExpressionBase innerTable, bool nullable)
 {
     throw new NotSupportedException();
 }