Exemplo n.º 1
0
        Expression VisitSelectExpression(SelectExpression selectExpression)
        {
            base.Visit(selectExpression);
            if (!RequiresRowNumberPaging(selectExpression))
            {
                return(selectExpression);
            }
            var subQuery = selectExpression.PushDownSubquery();

            foreach (var projection in subQuery.Projection)
            {
                selectExpression.AddToProjection(projection.LiftExpressionFromSubquery(subQuery));
            }
            if (subQuery.OrderBy.Count == 0)
            {
                subQuery.AddToOrderBy(
                    new Ordering(new SqlFunctionExpression("@@RowCount", typeof(int)), OrderingDirection.Asc));
            }
            var innerRowNumberExpression = new AliasExpression(
                RowNumberColumnName + (_counter != 0 ? $"{_counter}" : ""),
                new RowNumberExpression_SqlServer(subQuery.OrderBy));

            _counter++;
            subQuery.ClearOrderBy();
            subQuery.AddToProjection(innerRowNumberExpression, false);
            var rowNumberReferenceExpression = new ColumnReferenceExpression(innerRowNumberExpression, subQuery);
            var offset = subQuery.Offset ?? Expression.Constant(0);

            if (subQuery.Offset != null)
            {
                selectExpression.AddToPredicate
                    (Expression.GreaterThan(rowNumberReferenceExpression, offset));
                subQuery.Offset = null;
            }
            if (subQuery.Limit != null)
            {
                var constantValue = (subQuery.Limit as ConstantExpression)?.Value;
                var offsetValue   = (offset as ConstantExpression)?.Value;
                var limitExpression
                    = constantValue != null &&
                      offsetValue != null
                ? (Expression)Expression.Constant((int)offsetValue + (int)constantValue)
                : Expression.Add(offset, subQuery.Limit);
                selectExpression.AddToPredicate(
                    Expression.LessThanOrEqual(rowNumberReferenceExpression, limitExpression));
                subQuery.Limit = null;
            }
            return(selectExpression);
        }
Exemplo n.º 2
0
        internal static SelectExpression WhereAndSelectDatabaseExpressions(AdventureWorks adventureWorks)
        {
            QueryCompilationContext compilationContext = adventureWorks.GetService <IQueryCompilationContextFactory>()
                                                         .Create(async: false);
            SelectExpression databaseExpression = new SelectExpression(
                dependencies: new SelectExpressionDependencies(adventureWorks.GetService <IQuerySqlGeneratorFactory>(), adventureWorks.GetService <IRelationalTypeMappingSource>()),
                queryCompilationContext: (RelationalQueryCompilationContext)compilationContext);
            MainFromClause querySource = new MainFromClause(
                itemName: "product",
                itemType: typeof(Product),
                fromExpression: Expression.Constant(adventureWorks.ProductCategories));
            TableExpression tableExpression = new TableExpression(
                table: nameof(Product),
                schema: AdventureWorks.Production,
                alias: querySource.ItemName,
                querySource: querySource);

            databaseExpression.AddTable(tableExpression);
            IEntityType      productEntityType = adventureWorks.Model.FindEntityType(typeof(Product));
            IProperty        nameProperty      = productEntityType.FindProperty(nameof(Product.Name));
            ColumnExpression nameColumn        = new ColumnExpression(
                name: nameof(Product.Name), property: nameProperty, tableExpression: tableExpression);

            databaseExpression.AddToProjection(nameColumn);
            databaseExpression.AddToPredicate(Expression.GreaterThan(
                                                  left: new ExplicitCastExpression(
                                                      operand: new SqlFunctionExpression(
                                                          functionName: "LEN",
                                                          returnType: typeof(int),
                                                          arguments: new Expression[] { nameColumn }),
                                                      type: typeof(int)),
                                                  right: Expression.Constant(10)));
            return(databaseExpression.WriteLine());
        }
        Expression VisitSelectExpression(SelectExpression selectExpression)
        {
            base.Visit(selectExpression);
            if (!RequiresRowNumberPaging(selectExpression))
            {
                return(selectExpression);
            }
            SelectExpression selectExpression2 = selectExpression.PushDownSubquery();

            foreach (Expression item in selectExpression2.Projection)
            {
                selectExpression.AddToProjection(item.LiftExpressionFromSubquery(selectExpression2), true);
            }
            AliasExpression aliasExpression = new AliasExpression("row_number" + ((_counter != 0) ? $"{_counter}" : ""), new RowNumberExpression_DB2(selectExpression2.OrderBy));

            _counter++;
            selectExpression2.ClearOrderBy();
            selectExpression2.AddToProjection(aliasExpression, false);
            ColumnReferenceExpression left = new ColumnReferenceExpression(aliasExpression, selectExpression2);
            Expression expression          = selectExpression2.Offset ?? Expression.Constant(0);

            if (selectExpression2.Offset != null)
            {
                selectExpression.AddToPredicate(Expression.GreaterThan(left, expression));
                selectExpression2.Offset = null;
            }
            if (selectExpression2.Limit != null)
            {
                object     obj   = (selectExpression2.Limit as ConstantExpression)?.Value;
                object     obj2  = (expression as ConstantExpression)?.Value;
                Expression right = (obj != null && obj2 != null) ? ((Expression)Expression.Constant((int)obj2 + (int)obj)) : ((Expression)Expression.Add(expression, selectExpression2.Limit));
                selectExpression.AddToPredicate(Expression.LessThanOrEqual(left, right));
                selectExpression2.Limit = null;
            }
            return(selectExpression);
        }
Exemplo n.º 4
0
            private Expression VisitSelectExpression(SelectExpression selectExpression)
            {
                base.Visit(selectExpression);

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

                var subQuery = selectExpression.PushDownSubquery();

                if (subQuery.Projection.Count > 0)
                {
                    selectExpression.ExplodeStarProjection();
                }

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

                var innerRowNumberExpression = new AliasExpression(
                    RowNumberColumnName + (_counter != 0 ? $"{_counter}" : ""),
                    new RowNumberExpression(
                        subQuery.OrderBy
                        .Select(
                            o => new Ordering(
                                o.Expression is AliasExpression ae ? ae.Expression : o.Expression,
                                o.OrderingDirection))
                        .ToList()));

                _counter++;

                subQuery.ClearOrderBy();
                subQuery.AddToProjection(innerRowNumberExpression, resetProjectStar: false);

                var rowNumberReferenceExpression = new ColumnReferenceExpression(innerRowNumberExpression, subQuery);

                var offset = subQuery.Offset ?? Expression.Constant(0);

                if (subQuery.Offset != null)
                {
                    selectExpression.AddToPredicate(
                        Expression.GreaterThan(
                            rowNumberReferenceExpression,
                            ApplyConversion(offset, rowNumberReferenceExpression.Type)));

                    subQuery.Offset = null;
                }

                if (subQuery.Limit != null)
                {
                    var constantValue = (subQuery.Limit as ConstantExpression)?.Value;
                    var offsetValue   = (offset as ConstantExpression)?.Value;

                    var limitExpression
                        = constantValue != null &&
                          offsetValue != null
                            ? (Expression)Expression.Constant((int)offsetValue + (int)constantValue)
                            : Expression.Add(offset, subQuery.Limit);

                    selectExpression.AddToPredicate(
                        Expression.LessThanOrEqual(
                            rowNumberReferenceExpression,
                            ApplyConversion(limitExpression, rowNumberReferenceExpression.Type)));

                    subQuery.Limit = null;
                }

                return(selectExpression);
            }
Exemplo n.º 5
0
        public Expression CreateQueryExpression(Type elementType, DbContext context)
        {
            var targetType = context.Model.GetEntityTypes().SingleOrDefault(t => t.ClrType == elementType);

            Expression queryExpression;

            if (targetType.DefiningQuery != null)
            {
                queryExpression = targetType.DefiningQuery.Body;

                goto ApplyQueryFilters;
            }

            var rootType = targetType.RootType();

            var schemaName = rootType.Relational().Schema ?? context.Model.Relational().DefaultSchema;
            var tableName  = rootType.Relational().TableName;

            var table
                = new BaseTableExpression(
                      schemaName,
                      tableName,
                      tableName.Substring(0, 1).ToLower(),
                      rootType.ClrType);

            var materializer = CreateMaterializer(targetType, table);

            var projection = new ServerProjectionExpression(materializer);

            var selectExpression = new SelectExpression(projection, table);

            var discriminatingType = targetType;

            while (discriminatingType != null)
            {
                var discriminatorProperty = discriminatingType.Relational().DiscriminatorProperty;

                if (discriminatorProperty != null)
                {
                    selectExpression
                        = selectExpression.AddToPredicate(
                              new SqlInExpression(
                                  MakeColumnExpression(
                                      table,
                                      discriminatorProperty),
                                  Expression.NewArrayInit(
                                      discriminatorProperty.ClrType,
                                      from t in discriminatingType.GetDerivedTypesInclusive()
                                      where !t.IsAbstract()
                                      select Expression.Constant(
                                          t.Relational().DiscriminatorValue,
                                          discriminatorProperty.ClrType))));
                }

                discriminatingType = FindSameTabledPrincipalType(discriminatingType);
            }

            queryExpression = new EnumerableRelationalQueryExpression(selectExpression);

ApplyQueryFilters:

            var currentType = targetType;
            var recast = false;

            while (currentType != null)
            {
                if (currentType.QueryFilter != null)
                {
                    var filterBody = currentType.QueryFilter.Body;

                    var repointer
                        = new QueryFilterRepointingExpressionVisitor(
                              DbContextParameter.GetInstance(context.GetType()));

                    filterBody = repointer.Visit(filterBody);

                    // Use a method call instead of adding to the SelectExpression
                    // so the rewriting visitors are guaranteed to get their hands on the
                    // filter.
                    queryExpression
                        = Expression.Call(
                              queryableWhereMethodInfo.MakeGenericMethod(currentType.ClrType),
                              queryExpression,
                              Expression.Quote(
                                  Expression.Lambda(
                                      new QueryFilterExpression(filterBody),
                                      currentType.QueryFilter.Parameters)));

                    recast |= currentType != targetType;
                }

                currentType = currentType.BaseType;
            }

            if (recast)
            {
                queryExpression
                    = Expression.Call(
                          queryableCastMethodInfo.MakeGenericMethod(targetType.ClrType),
                          queryExpression);
            }

            return(queryExpression);
        }