diff --git a/notes/helloshop/pagging.md b/notes/helloshop/pagging.md new file mode 100644 index 0000000..c3ce78f --- /dev/null +++ b/notes/helloshop/pagging.md @@ -0,0 +1,105 @@ +# 分页排序和多条件查询 + +## 分页参数 + +请求应使用 GET 方法 + +```shell +http://localhost:8080/api/products?keyword=test&pagenumber=1&pagesize=5&orderby=id desc,price asc +``` + +响应返回如下 + +```json +{ + "totalCount": 100, + "items": [ + { + "id": 1, + "name": "test", + "price": 100 + }, + { + "id": 2, + "name": "test", + "price": 200 + } + ] +} +``` + +## 分页请求模型 + +```csharp +public class PagedAndSortedRequest : PagedRequest +{ + public string? OrderBy { get; init; } +} +``` + +## 分页响应模型 + +```csharp +public class PagedResponse(IReadOnlyList items, int totalCount) +{ + public IReadOnlyList Items { get; init; } = items; + + public int TotalCount { get; init; } = totalCount; +} +``` + +## 扩展 IQueryable 以便通过属性名称排序 + +```shell +QueryableOrderByExtensions.cs +``` + +将字符串条件转化为排序表达式 + +```csharp +IOrderedQueryable OrderBy(IQueryable source, string propertyName) +``` + +## 扩展 IQueryable 以便搜索和排序 + +```shell +QueryableExtensions.cs +``` + +扩展分页和排序方法 + +```csharp +IQueryable SortBy(this IQueryable query, string? orderBy = null); +IQueryable PageBy(this IQueryable query, PagedRequest pagedRequest) +IQueryable SortAndPageBy(this IQueryable query, PagedAndSortedRequest? pagedAndSortedRequest = null); +``` + +再扩展一个 WhereIf 条件查询 + +```csharp +IQueryable WhereIf(this IQueryable source, bool condition, Expression> predicate); +``` + +## 在 API 控制器中使用扩展方法 + +```csharp +[HttpGet] +[Authorize(IdentityPermissions.Users.Default)] +public async Task>> GetUsers([FromQuery] UserListRequest model) +{ + IQueryable users = dbContext.Set(); + + if (model.Keyword is not null) + { + users = users.Where(e => e.UserName != null && e.UserName.Contains(model.Keyword)); + } + + users = users.WhereIf(model.PhoneNumber is not null, e => e.PhoneNumber == model.PhoneNumber); + + var pagedUsers = users.SortAndPageBy(model); + + var list = new List(); + + return new PagedResponse(mapper.Map>(await pagedUsers.ToListAsync()), await users.CountAsync()); +} +```