Efficient pagination using OFFSET-FETCH on SQL Server.
| ID | Name | Category | Price | Stock | Rating | Reviews | SKU |
|---|---|---|---|---|---|---|---|
| 24985 | Bulk Product b39b5520 | Home & Garden | $16.12 | 100 | ★ 0.9 | 14 | BULK-99a56473 |
| 24986 | Bulk Product 86c9718f | Sports & Outdoors | $83.97 | 450 | ★ 1.8 | 33 | BULK-1ccea3b8 |
| 24987 | Bulk Product ef09aaab | Sports & Outdoors | $482.78 | 339 | ★ 3.6 | 72 | BULK-80dc527f |
| 24988 | Bulk Product fc346edc | Home & Garden | $890.94 | 484 | ★ 0.9 | 8 | BULK-f7c00ac9 |
| 24989 | Bulk Product 231dc7a2 | Clothing | $417.94 | 419 | ★ 3.1 | 80 | BULK-43dbe707 |
| 24990 | Bulk Product f20e3274 | Sports & Outdoors | $454.10 | 202 | ★ 4.4 | 77 | BULK-efb85147 |
| 24991 | Bulk Product da93319e | Books | $919.16 | 244 | ★ 3.8 | 69 | BULK-cc1c37f5 |
| 24992 | Bulk Product e0e774ec | Toys & Games | $881.11 | 80 | ★ 4.1 | 18 | BULK-caeddc6c |
| 24993 | Bulk Product 3fdc7f31 | Clothing | $514.46 | 120 | ★ 0.7 | 32 | BULK-0981347c |
| 24994 | Bulk Product 7d6cc982 | Electronics | $248.92 | 412 | ★ 2.7 | 55 | BULK-cdf65de2 |
| 24995 | Bulk Product 05e65829 | Sports & Outdoors | $109.27 | 402 | ★ 1.5 | 63 | BULK-12cf1700 |
| 24996 | Bulk Product 908bb789 | Toys & Games | $885.71 | 479 | ★ 2.5 | 69 | BULK-c044aa44 |
| 24997 | Bulk Product 10e106e9 | Home & Garden | $303.92 | 169 | ★ 2.8 | 44 | BULK-ee7d2b37 |
| 24998 | Bulk Product 427e1267 | Electronics | $505.68 | 88 | ★ 0.9 | 89 | BULK-b6059874 |
| 24999 | Bulk Product 7cb08069 | Electronics | $800.30 | 29 | ★ 3.2 | 73 | BULK-0a14347d |
| 25000 | Bulk Product 44e65772 | Electronics | $599.69 | 35 | ★ 3.0 | 73 | BULK-91ba76a4 |
// Efficient pagination with Skip and Take
public async Task<PaginatedResult<DemoProduct>> GetPaginatedProductsAsync(int page, int pageSize)
{
// Get total count (cached if possible)
var totalCount = await _context.DemoProducts.CountAsync(p => p.IsActive);
// Get page of results
var items = await _context.DemoProducts
.Where(p => p.IsActive)
.OrderBy(p => p.Id) // Important: Must have ORDER BY for consistent paging
.Skip((page - 1) * pageSize) // OFFSET in SQL
.Take(pageSize) // FETCH NEXT in SQL
.AsNoTracking() // No tracking needed for read-only
.ToListAsync();
return new PaginatedResult<DemoProduct>
{
Items = items,
TotalCount = totalCount,
Page = page,
PageSize = pageSize
};
}