Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow nulls in getReferenceAsync #7

Merged
merged 5 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased: 2.0.1

### Fixed

- Properly annotate the `getReferenceAsync` delegate to allow nulls, which fixes the mismatch in analysis.

## 2.0.0 - 2022-11-05

This version introduces breaking changes. Make sure to read on them in the Changed section below.
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ services.AddPagination(options =>

Check the [`PaginationOptions`](https://github.com/mrahhal/MR.AspNetCore.Pagination/blob/main/src/MR.AspNetCore.Pagination/PaginationOptions.cs) class to see what you can configure.

And then just inject `IPaginationService` in your controller/page and use it. The [returned result](https://github.com/mrahhal/MR.AspNetCore.Pagination/blob/main/src/MR.AspNetCore.Pagination/PaginationResult.cs) is either a `KeysetPaginationResult<>` or an `OffsetPaginationResult<>`, each containing all the info you need for this pagination result.
And then just inject `IPaginationService` in your controller/page and use it. The [returned result](https://github.com/mrahhal/MR.AspNetCore.Pagination/blob/main/src/MR.AspNetCore.Pagination/PaginationResult.cs) is either a `KeysetPaginationResult<>` or an `OffsetPaginationResult<>`, each containing all the info you need for this pagination result.

Do a keyset pagination:

Expand Down Expand Up @@ -110,6 +110,27 @@ var result = _paginationService.OffsetPaginate(orders);

There's a helper `PaginationActionDetector` class that can be used with reflection, for example in ASP.NET Core conventions, which can tell you whether the action method returns a pagination result or not. This is what the MR.AspNetCore.Pagination.Swashbuckle package uses to configure swagger for those apis.

## Handling null references (reference has been deleted from the db)

The `getReferenceAsync` delegate parameter on `KeysetPaginateAsync` that you'll provide allows returning nulls. The behavior when that happens is to always return the first page (enforcing Forward direction).

If you want to have a special way to handle this, you'll simply have to do that logic in the `getReferenceAsync` delegate you'll provide. Here's an example:
```cs
var result = await _paginationService.KeysetPaginateAsync(
query,
b => b.Descending(x => x.Created),
async id =
{
var reference = await _dbContext.Users.FindAsync(int.Parse(id));
if (reference == null)
{
// Throw a custom exception which will be captured by some middleware to process.
throw new MyKeysetPaginationReferenceIsNullException();
}
return reference;
};
```

## Query model as an argument

All methods also have overloads that accept the pagination query model directly as an argument, as opposed to parsing it from the request query.
Expand Down
1 change: 1 addition & 0 deletions samples/Basic/Pages/Index.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public IndexModel(

public async Task OnGet()
{
#nullable enable
var query = _dbContext.Users;

Users = await _paginationService.KeysetPaginateAsync(
Expand Down
1 change: 1 addition & 0 deletions samples/Basic/Pages/Keyset2.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public Keyset2Model(

public async Task OnGet()
{
#nullable enable
var query = _dbContext.Users;

Users = await _paginationService.KeysetPaginateAsync(
Expand Down
1 change: 1 addition & 0 deletions samples/Basic/Pages/Keyset3.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public Keyset3Model(

public async Task OnGet()
{
#nullable enable
var query = _dbContext.Posts;

Posts = await _paginationService.KeysetPaginateAsync(
Expand Down
12 changes: 6 additions & 6 deletions src/MR.AspNetCore.Pagination/PaginationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface IPaginationService
Task<KeysetPaginationResult<TOut>> KeysetPaginateAsync<T, TOut>(
IQueryable<T> source,
Action<KeysetPaginationBuilder<T>> builderAction,
Func<string, Task<T>> getReferenceAsync,
Func<string, Task<T?>> getReferenceAsync,
Func<IQueryable<T>, IQueryable<TOut>> map,
KeysetQueryModel queryModel)
where T : class
Expand All @@ -44,7 +44,7 @@ Task<KeysetPaginationResult<TOut>> KeysetPaginateAsync<T, TOut>(
Task<KeysetPaginationResult<TOut>> KeysetPaginateAsync<T, TOut>(
IQueryable<T> source,
Action<KeysetPaginationBuilder<T>> builderAction,
Func<string, Task<T>> getReferenceAsync,
Func<string, Task<T?>> getReferenceAsync,
Func<IQueryable<T>, IQueryable<TOut>> map,
int? pageSize = null)
where T : class
Expand Down Expand Up @@ -134,7 +134,7 @@ public static Task<KeysetPaginationResult<T>> KeysetPaginateAsync<T>(
this IPaginationService @this,
IQueryable<T> source,
Action<KeysetPaginationBuilder<T>> builderAction,
Func<string, Task<T>> getReferenceAsync,
Func<string, Task<T?>> getReferenceAsync,
KeysetQueryModel queryModel)
where T : class
=> @this.KeysetPaginateAsync(source, builderAction, getReferenceAsync, query => query, queryModel);
Expand All @@ -153,7 +153,7 @@ public static Task<KeysetPaginationResult<T>> KeysetPaginateAsync<T>(
this IPaginationService @this,
IQueryable<T> source,
Action<KeysetPaginationBuilder<T>> builderAction,
Func<string, Task<T>> getReferenceAsync,
Func<string, Task<T?>> getReferenceAsync,
int? pageSize = null)
where T : class
=> @this.KeysetPaginateAsync(source, builderAction, getReferenceAsync, query => query, pageSize);
Expand Down Expand Up @@ -242,7 +242,7 @@ public PaginationService(
public async Task<KeysetPaginationResult<TOut>> KeysetPaginateAsync<T, TOut>(
IQueryable<T> source,
Action<KeysetPaginationBuilder<T>> builderAction,
Func<string, Task<T>> getReferenceAsync,
Func<string, Task<T?>> getReferenceAsync,
Func<IQueryable<T>, IQueryable<TOut>> map,
KeysetQueryModel queryModel)
where T : class
Expand Down Expand Up @@ -302,7 +302,7 @@ public async Task<KeysetPaginationResult<TOut>> KeysetPaginateAsync<T, TOut>(
public Task<KeysetPaginationResult<TOut>> KeysetPaginateAsync<T, TOut>(
IQueryable<T> source,
Action<KeysetPaginationBuilder<T>> builderAction,
Func<string, Task<T>> getReferenceAsync,
Func<string, Task<T?>> getReferenceAsync,
Func<IQueryable<T>, IQueryable<TOut>> map,
int? pageSize = null)
where T : class
Expand Down
2 changes: 1 addition & 1 deletion version.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<VersionPrefix>2.0.0</VersionPrefix>
<VersionPrefix>2.0.1</VersionPrefix>
</PropertyGroup>
</Project>