Exemplo n.º 1
0
        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();
            }
        }
Exemplo n.º 2
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();
            }
        }
Exemplo n.º 3
0
        private void IncludeCollection(IQuerySource querySource, Type resultType, Expression accessorLambda, INavigation navigation)
        {
            var selectExpression = QueryCompilationContext.FindSelectExpression(querySource);

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

            foreach (var property in primaryKeyProperties)
            {
                selectExpression
                .AddToOrderBy(
                    QueryCompilationContext.GetColumnName(property),
                    property,
                    querySource,
                    OrderingDirection.Asc);
            }

            var targetEntityType = navigation.GetTargetType();
            var targetTableName  = QueryCompilationContext.GetTableName(targetEntityType);

            var targetSelectExpression = new SelectExpression();

            var targetTableAlias
                = CreateUniqueAlias(selectExpression, targetTableName.First().ToString().ToLower());

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

            targetSelectExpression.AddTable(targetTableExpression);

            foreach (var property in targetEntityType.Properties)
            {
                targetSelectExpression
                .AddToProjection(
                    QueryCompilationContext.GetColumnName(property),
                    property,
                    querySource);
            }

            var innerJoinSelectExpression
                = selectExpression.Clone(
                      ((ColumnExpression)selectExpression.OrderBy.First().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 innerJoinExpression
                = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression);

            targetSelectExpression.AddToOrderBy(selectExpression.OrderBy);

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

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

            Expression
                = Expression.Call(
                      QueryCompilationContext.QueryMethodProvider.IncludeCollectionMethod
                      .MakeGenericMethod(resultType),
                      QueryContextParameter,
                      Expression,
                      Expression.Constant(navigation),
                      Expression.Call(
                          QueryCompilationContext.QueryMethodProvider.QueryMethod
                          .MakeGenericMethod(typeof(IValueReader)),
                          QueryContextParameter,
                          Expression.Constant(new CommandBuilder(targetSelectExpression, QueryCompilationContext)),
                          Expression.Lambda(
                              Expression.Call(
                                  _createValueReaderForIncludeMethodInfo,
                                  QueryContextParameter,
                                  readerParameter,
                                  Expression.Constant(targetEntityType)),
                              readerParameter)),
                      accessorLambda);
        }
Exemplo n.º 4
0
        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)));
                }
            }
        }