Skip to content

Commit 7cafe32

Browse files
sunghwan2789michaelstaib
authored andcommitted
Added support for between both cursors (#7800)
1 parent 6824099 commit 7cafe32

File tree

4 files changed

+118
-2
lines changed

4 files changed

+118
-2
lines changed

src/HotChocolate/Pagination/src/Pagination.EntityFramework/Extensions/PagingQueryableExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ public static async ValueTask<Page<T>> ToPageAsync<T>(
9999
if (arguments.After is not null)
100100
{
101101
var cursor = CursorParser.Parse(arguments.After, keys);
102-
source = source.Where(BuildWhereExpression<T>(keys, cursor, forward));
102+
source = source.Where(BuildWhereExpression<T>(keys, cursor, true));
103103
}
104104

105105
if (arguments.Before is not null)
106106
{
107107
var cursor = CursorParser.Parse(arguments.Before, keys);
108-
source = source.Where(BuildWhereExpression<T>(keys, cursor, forward));
108+
source = source.Where(BuildWhereExpression<T>(keys, cursor, false));
109109
}
110110

111111
if (arguments.First is not null)

src/HotChocolate/Pagination/test/Pagination.EntityFramework.Tests/PagingHelperTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,27 @@ public async Task Fetch_First_2_Items_Third_Page()
7676
page.MatchMarkdownSnapshot();
7777
}
7878

79+
[Fact]
80+
public async Task Fetch_First_2_Items_Between()
81+
{
82+
// Arrange
83+
var connectionString = CreateConnectionString();
84+
await SeedAsync(connectionString);
85+
86+
// .. get first page
87+
var arguments = new PagingArguments(4);
88+
await using var context = new CatalogContext(connectionString);
89+
var page = await context.Products.OrderBy(t => t.Name).ThenBy(t => t.Id)
90+
.ToPageAsync(arguments);
91+
92+
// Act
93+
arguments = new PagingArguments(2, after: page.CreateCursor(page.First!), before: page.CreateCursor(page.Last!));
94+
page = await context.Products.OrderBy(t => t.Name).ThenBy(t => t.Id).ToPageAsync(arguments);
95+
96+
// Assert
97+
page.MatchMarkdownSnapshot();
98+
}
99+
79100
[Fact]
80101
public async Task Fetch_Last_2_Items()
81102
{
@@ -118,6 +139,29 @@ public async Task Fetch_Last_2_Items_Before_Last_Page()
118139
page.MatchMarkdownSnapshot();
119140
}
120141

142+
[Fact]
143+
public async Task Fetch_Last_2_Items_Between()
144+
{
145+
// Arrange
146+
var connectionString = CreateConnectionString();
147+
await SeedAsync(connectionString);
148+
149+
// .. get last page
150+
var arguments = new PagingArguments(last: 4);
151+
await using var context = new CatalogContext(connectionString);
152+
var page = await context.Products
153+
.OrderBy(t => t.Name)
154+
.ThenBy(t => t.Id)
155+
.ToPageAsync(arguments);
156+
157+
// Act
158+
arguments = new PagingArguments(after: page.CreateCursor(page.First!), last: 2, before: page.CreateCursor(page.Last!));
159+
page = await context.Products.OrderBy(t => t.Name).ThenBy(t => t.Id).ToPageAsync(arguments);
160+
161+
// Assert
162+
page.MatchMarkdownSnapshot();
163+
}
164+
121165
[Fact]
122166
public async Task Batch_Fetch_First_2_Items()
123167
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Fetch_First_2_Items_Between
2+
3+
```json
4+
[
5+
{
6+
"Id": 2,
7+
"Name": "Product 0-1",
8+
"Description": null,
9+
"Price": 0.0,
10+
"ImageFileName": null,
11+
"TypeId": 1,
12+
"Type": null,
13+
"BrandId": 1,
14+
"Brand": null,
15+
"AvailableStock": 0,
16+
"RestockThreshold": 0,
17+
"MaxStockThreshold": 0,
18+
"OnReorder": false
19+
},
20+
{
21+
"Id": 11,
22+
"Name": "Product 0-10",
23+
"Description": null,
24+
"Price": 0.0,
25+
"ImageFileName": null,
26+
"TypeId": 1,
27+
"Type": null,
28+
"BrandId": 1,
29+
"Brand": null,
30+
"AvailableStock": 0,
31+
"RestockThreshold": 0,
32+
"MaxStockThreshold": 0,
33+
"OnReorder": false
34+
}
35+
]
36+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Fetch_Last_2_Items_Between
2+
3+
```json
4+
[
5+
{
6+
"Id": 9998,
7+
"Name": "Product 99-97",
8+
"Description": null,
9+
"Price": 0.0,
10+
"ImageFileName": null,
11+
"TypeId": 1,
12+
"Type": null,
13+
"BrandId": 100,
14+
"Brand": null,
15+
"AvailableStock": 0,
16+
"RestockThreshold": 0,
17+
"MaxStockThreshold": 0,
18+
"OnReorder": false
19+
},
20+
{
21+
"Id": 9999,
22+
"Name": "Product 99-98",
23+
"Description": null,
24+
"Price": 0.0,
25+
"ImageFileName": null,
26+
"TypeId": 1,
27+
"Type": null,
28+
"BrandId": 100,
29+
"Brand": null,
30+
"AvailableStock": 0,
31+
"RestockThreshold": 0,
32+
"MaxStockThreshold": 0,
33+
"OnReorder": false
34+
}
35+
]
36+
```

0 commit comments

Comments
 (0)