我正在用ef学习asp.net核心剃须刀页面。我想用我的桌子实现分页,我已经检查了本教程
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-2.1
但是它仅支持前后,我已经研究了很长时间,所有解决方案都与asp.net核心mvc有关,但是我使用的是剃刀页面,我的项目中没有控制器,任何想法实施?
这就是我想要实现的效果
<form method="get" asp-page="./Index">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
@{
var totalPages = Model.Products.Count % 2 == 0 ? Model.Products.Count / 2 : Model.Products.Count / 2 + 1;
}
@for (int i = 1; i <= totalPages; i++)
{
<li><a asp-page="./Index" asp-route-id="@i">@i</a></li>
}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</form>
cshtml.cs
public async Task OnGetAsync(string sortOrder, string searchString, string shopString, string statusString, int page)
{}
答案 0 :(得分:13)
分页相对简单。有可用的库可以帮您完成,但是我开始发现它们比它们值得的麻烦更多。
您需要从请求中获取三条信息(或设置为默认值):
页码和页面大小为您提供“跳过”和“获取”值:
var skip = (page - 1) * size;
var take = size;
然后您可以通过以下方式获取结果:
var pageOfResults = await query.Skip(skip).Take(take).ToListAsync();
query
是IQueryable
的地方-直接使用您的DbSet
或应用DbSet
子句的Where
,OrderBy
等
然后,您只需要统计项目总数即可计算页面:
var count = await query.CountAsync();
专业提示,您可以通过以下操作并行化两个查询(结果和总数):
var resultsTask = query.Skip(skip).Take(take).ToListAsync();
var countTask = query.CountAsync();
var results = await resultsTask;
var count = await countTask;
任务热返回或已启动。 await
关键字仅保留其余代码的延续,直到任务完成。结果,如果您等待每一行,它们将按顺序完成,但是如果您先启动这两行,然后再等待每一行,则它们将并行处理。
无论如何,一旦您有了计数:
var totalPages = (int)Math.Ceil(Decimal.Divide(count, size));
var firstPage = 1;
var lastPage = totalPages;
var prevPage = Math.Max(page - 1, firstPage);
var nextPage = Math.Min(page + 1, lastPage);
注意:您可以根据分别等于firstPage
还是lastPage
来确定是否显示第一个/上一个和最后一个/下一个按钮。
然后,使用此信息构建您自己的模型,然后可以将其发送到视图以呈现结果并生成分页HTML。
答案 1 :(得分:1)
您可以使用JW.Pager
NuGet软件包(https://www.nuget.org/packages/JW.Pager/)
这是一个示例剃须刀页面模型,可分页显示150个项目:
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.RazorPages;
using JW;
namespace RazorPagesPagination.Pages
{
public class IndexModel : PageModel
{
public IEnumerable<string> Items { get; set; }
public Pager Pager { get; set; }
public void OnGet(int p = 1)
{
// generate list of sample items to be paged
var dummyItems = Enumerable.Range(1, 150).Select(x => "Item " + x);
// get pagination info for the current page
Pager = new Pager(dummyItems.Count(), p);
// assign the current page of items to the Items property
Items = dummyItems.Skip((Pager.CurrentPage - 1) * Pager.PageSize).Take(Pager.PageSize);
}
}
}
这是剃刀页面页面,其中包含分页列表和分页器控件的html:
@page
@model RazorPagesPagination.Pages.IndexModel
<!-- items being paged -->
<table class="table table-sm table-striped table-bordered">
@foreach (var item in Model.Items)
{
<tr>
<td>@item</td>
</tr>
}
</table>
<!-- pager -->
@if (Model.Pager.Pages.Any())
{
<nav class="table-responsive">
<ul class="pagination justify-content-center d-flex flex-wrap">
@if (Model.Pager.CurrentPage > 1)
{
<li class="page-item">
<a class="page-link" href="/">First</a>
</li>
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.CurrentPage - 1)">Previous</a>
</li>
}
@foreach (var p in Model.Pager.Pages)
{
<li class="page-item @(p == Model.Pager.CurrentPage ? "active" : "")">
<a class="page-link" href="/?p=@p">@p</a>
</li>
}
@if (Model.Pager.CurrentPage < Model.Pager.TotalPages)
{
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.CurrentPage + 1)">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.TotalPages)">Last</a>
</li>
}
</ul>
</nav>
}
有关更多详细信息,我在http://jasonwatmore.com/post/2018/10/15/aspnet-core-razor-pages-pagination-example
上发布了带有示例项目的完整教程。答案 2 :(得分:0)
我为.net Core Razor Pages创建了一个分页taghelper,可以在html标签或appsettings.json中对其进行配置,以显示/隐藏上一个,下一个,倒数第二个按钮,最大显示页面数以及更多自定义设置。可用
该项目可作为nuget包(和github)安装:
Install-Package LazZiya.TagHelpers -Version 1.0.2
在此处查看安装步骤: http://ziyad.info/en/articles/21-Paging_TagHelper_for_ASP_NET_Core
实时演示和所有设置: http://demo.ziyad.info/en/paging
使用appsettings.json进行分页配置将有助于获得更清晰的html代码,并且可以更改应用程序中所有或特定分页taghelper的分页设置。
答案 3 :(得分:0)
我做了这个实现,将有关该主题的一些答案混合在一起,希望对您有所帮助。
添加一个PagedResultBase
类(您可以扩展添加所需的其他属性):
public abstract class PagedResultBase
{
public int CurrentPage { get; set; }
public int PageCount { get; set; }
public int PageSize { get; set; }
public int RowCount { get; set; }
}
添加一个PagedResult
类:
public class PagedResult<T> : PagedResultBase where T : class
{
public ICollection<T> Results { get; set; }
public PagedResult()
{
Results = new List<T>();
}
}
添加扩展名为IQueryableExtensions
的{{1}}:
GetPagedResult
您已完成:
public static class IQueryableExtensions
{
public async static Task<PagedResult<T>> GetPagedResultAsync<T>(this IQueryable<T> query, int currentPage, int pageSize) where T : class
{
var skip = (currentPage - 1) * pageSize;
var take = pageSize;
var rowCount = await query.CountAsync();
var results = await query.Skip(skip).Take(take).ToListAsync();
var pagedResult = new PagedResult<T> {
CurrentPage = currentPage,
PageCount = (int)Math.Ceiling(decimal.Divide(rowCount, pageSize)),
PageSize = pageSize,
RowCount = rowCount,
Results = results
};
return pagedResult;
}
}