/// <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> public virtual Expression VisitRowNumber(RowNumberExpression rowNumberExpression) { Check.NotNull(rowNumberExpression, nameof(rowNumberExpression)); Sql.Append("ROW_NUMBER() OVER("); GenerateOrderBy(rowNumberExpression.Orderings); Sql.Append(") AS ").Append(SqlGenerator.DelimitIdentifier(rowNumberExpression.ColumnExpression.Name)); return rowNumberExpression; }
private bool Equals([NotNull] RowNumberExpression other) => _orderings.SequenceEqual(other._orderings);
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(alias.Alias ?? 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 ?? Expression.Constant(0); if (subQuery.Offset != null) { predicate = Expression.GreaterThan(columnExpression, offset); } 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); var expression = Expression.LessThanOrEqual(columnExpression, limitExpression); if (predicate != null) { expression = Expression.AndAlso(predicate, expression); } predicate = expression; } selectExpression.Predicate = predicate; return selectExpression; }