【问题标题】:ASP.net Core 3.1 Razor page Paging control not working with dapper datasetASP.net Core 3.1 Razor 页面分页控件不适用于 dapper 数据集
【发布时间】:2020-07-12 20:05:37
【问题描述】:

我是 asp.net core 的新手,我正在尝试在 ASP.net core 3.1 Razor Page 项目中使用分页器控件LazZiya.TagHelpers 进行分页以显示新项目,由于某种原因它显示了所有新闻项目(总共 20 ) 在新闻页面上,但寻呼机控件似乎显示正确的数字

似乎这个分页控件只适用于 EF 而不是 Dapper,我试图让它与不起作用的 dapper 一起工作?下面是与 Dapper 相关的代码以及使用 EF 的工作代码。如果我也可以使它与 Dapper 一起使用,我将不胜感激(以我有限的知识,这似乎是不可能的)

出于测试目的,我将页面大小设置为 3,因此它应该在页面上显示 3 个项目,而不是在页面上显示所有 20 个项目,

似乎寻呼机控件没有绑定到 List eNewsList= await NewsService.GetNews(1);

     public class NewsModel : PageModel
{
    public IEnumerable<News> NewsList { get; set; }

    public INewsService NewsService { get; }

    public NewsModel(INewsService newsService)
    {
        NewsService = newsService ?? throw new ArgumentNullException(nameof(newsService));
    }

    [BindProperty]
    public IEnumerable<News> eNewsList { get; set; }

    [BindProperty]
    public int TotalRecords { get; set; }

    [BindProperty]
    public int PageNo { get; set; }

    [BindProperty]
    public int PageSize { get; set; }
    // public 

    public async Task OnGet( int p=1, int s=3)
    {

        eNewsList = await NewsService.GetNews(1);     
        TotalRecords = eNewsList.Count();
        eNewsList.Skip((p - 1) * s).Take(s);
        PageNo = p;
        PageSize = s;

        //NewsList.ToList();
    }


}

代码

<div class="container">
    <div class="row">
        @foreach (var item in Model.eNewsList)
        {
            <div class="col-xl-4 col-lg-4 col-md-6">
                <div class="card">
                    <img src="images/NewsImages/@item.NewsImage" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">@item.NewsHeading</h5>
                        @if (item.NewsBrief.Length > 50)
                        {
                            <p class="card-text">@item.NewsBrief.Substring(0, 50)...</p>}
                        else
                        {
                            <p class="card-text">@item.NewsBrief</p>
                        }
                        <a href="/news/@item.NewsID/@item.NewsHeading.Replace(" ", "-").ToLower()" class="btn btn-primary">Read More</a>
                    </div>
                </div>
            </div>
        }

        <div class="row">
            <div class="col-12">
                <paging  total-records="Model.TotalRecords"
                        page-no="Model.PageNo"
                        page-size="Model.PageSize">
                </paging>
            </div>
        </div>

    </div>
</div>

简洁的代码

 // Get all News
        public async Task<List<News>> GetNews(int langID)
        {
            IEnumerable<News> newslist;
            using (var conn = new SqlConnection(_configuration.Value))
            {
                string query = "select * from dbo.News Where LanguageID ="+ langID;
                        query = query +" AND NewsActive =1 AND NewsVisible=1 order by NewsDate Desc";

                conn.Open();
                try
                {
                    newslist = await conn.QueryAsync<News>(query, commandType: CommandType.Text);

                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    conn.Close();
                }

            }
            return newslist.ToList();
        }

我不确定如何将数据 eNewslist 绑定到寻呼机控件

我正在使用来自http://www.ziyad.info/en/articles/21-Paging_TagHelper_ASP_NET_Core 的寻呼机控件

以下代码在我与 EF 一起使用时有效

使用 EF 的工作代码

<div class="container">
    <div class="row">
        @foreach (var item in Model.eNewsList)
        {
            <div class="col-xl-4 col-lg-4 col-md-6">
                <div class="card">
                    <img src="https://www.habtoor.com/images/NewsImages/@item.NewsImage" class="card-img-top" alt="...">
                    <div class="card-body">
                        <h5 class="card-title">@item.NewsHeading</h5>
                        @if (item.NewsBrief.Length > 50)
                        {
                            <p class="card-text">@item.NewsBrief.Substring(0, 50)...</p>}
                        else
                        {
                            <p class="card-text">@item.NewsBrief</p>
                        }
                        <a href="/news/@item.NewsID/@item.NewsHeading.Replace(" ", "-").ToLower()" class="btn btn-primary">Read More</a>
                    </div>
                </div>
            </div>
        }

        <div class="row">
            <div class="col-12">
                <paging total-records="Model.TotalRecords"
                        page-no="Model.P"
                        page-size="Model.S"
                        show-prev-next="true"
                        show-total-pages="false"
                        show-total-records="false"
                        show-page-size-nav="false"
                        show-gap="true"
                        show-first-numbered-page="true"
                        show-last-numbered-page="true"
                        gap-size="2"
                        max-displayed-pages="8"
                        query-string-key-page-no="p"
                        query-string-key-page-size="s"
                        query-string-value="@@(Request.QueryString.Value)"
                        page-size-nav-block-size="10"
                        page-size-nav-max-items="5"
                        page-size-nav-on-change="get"
                        page-size-nav-form-method="this.form.submit();"
                        class="row"
                        class-paging-control-div="col"
                        class-info-div="col"
                        class-page-size-div="col"
                        class-paging-control="pagination"
                        class-active-page="disabled"
                        class-disabled-jumping-button="disabled"
                        class-total-pages="badge badge-secondary"
                        class-total-records="badge badge-info"
                        text-page-size="Items per page:"
                        text-total-pages="pages"
                        text-total-records="records"
                        text-first="&laquo;"
                        text-last="&raquo;"
                        text-previous="&lsaquo;"
                        text-next="&rsaquo;"
                        sr-text-first="First"
                        sr-text-last="Last"
                        sr-text-previous="Previous"
                        sr-text-next="Next">
                </paging>
            </div>
        </div>

    </div>
</div>

后面的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using BookListRazor.Data;
using BookListRazor.Model;
using Microsoft.EntityFrameworkCore;

namespace BookListRazor.Pages
{
    public class NewsModel : PageModel
    {
        // for EF
        private readonly ApplicationDbContext _db;

        public IEnumerable<News> NewsList { get; set; }

        public INewsService NewsService { get; }

        //constructor
        public NewsModel(INewsService newsService, ApplicationDbContext db)
        {
            //for EF
            _db = db;

            //For Dapper
            NewsService = newsService ?? throw new ArgumentNullException(nameof(newsService));
        }


        [BindProperty]
        public IEnumerable<News> eNewsList { get; set; }

        [BindProperty]
        public int TotalRecords { get; set; }

        [BindProperty(SupportsGet = true)]
        public int P { get; set; }

        [BindProperty(SupportsGet = true)]
        public int S { get; set; }

        // public 

        public async Task OnGet()
        {

            //code block for pager to work with EF only
            //pager doesnt work with dapper
            P = 1;
            S = 3;

            //var pageQS=1;
            if (!String.IsNullOrEmpty(HttpContext.Request.Query["p"]))
            {
                P = int.Parse(HttpContext.Request.Query["p"]);
            }

            var query = await _db.News.OrderByDescending(x => x.NewsDate).Where(x => x.LanguageID == 1 && x.NewsActive==true && x.NewsVisible==true).ToListAsync();
            TotalRecords = query.Count();

            //steps for paging
            eNewsList = await _db.News.OrderByDescending(x=>x.NewsDate).Where(x =>x.LanguageID==1).Skip((P - 1) * S).Take(S).ToListAsync();


            // Dapper without pagging
           // NewsList = await NewsService.GetNews(1);
        }


    }
}

【问题讨论】:

    标签: asp.net asp.net-core paging razor-pages


    【解决方案1】:

    下面是后端分页的简化实现。

    public IEnumerable<News> eNewsList { get; set; }
    
    public int TotalRecords { get; set; }
    
    [BindProperty(SupportsGet = true)]
    public int P { get; set; }
    
    [BindProperty(SupportsGet = true)]
    public int S { get; set; }
    
    public async Task OnGetAsync()
    {
        var query = await NewsService.GetNews(1);
    
        TotalRecords = query.Count();
    
        eNewsList = await NewsService.GetNews(1).Skip((P - 1) * S).Take(S).ToListAsync();
    }
    

    请同时考虑以下注意事项:

    1 - 不要获取整个数据集,只获取一次要显示的数量

    由于我不知道NewsService.GetNews(1) 是什么,我想它正在返回一整套记录。

    不建议返回完整的记录集,因为它会消耗大量的内存、带宽和处理时间。我建议使用某种 EF linq 实现来避免过度处理问题。例如:

    var records = dbContext.Set<News>()
                           .AsNoTracking()
                           .Where(**some search filter**);
    

    这样的实现将被转换为一个查询,直到你调用.ToList().ToListAsync() 才会执行。这样您就可以确保您只返回请求数量的记录。

    当您调用 .Count() 时,它将仅返回记录数,而不获取整个数据集。

    2 - 在分页前进行记录排序

    如果您使用任何类型的分页,在分页项目之前对记录进行排序非常重要,因此您可以获得具有相同顺序的下一页记录,例如

    var records = await NewsSerive.GetNews(1)
                        .OrderBy(x => x.Name)
                        .Skip((P - 1)*S).Take(S)
                        .ToListAsync();
    

    3 - 页面大小设置

    关于PagingTagHelper 的另一个注意事项,如果要将页面值更改为默认值以外的其他值,请使用demo page 中所述的[page-size-dropdown-items] 属性

    【讨论】:

    • 我正在使用 Dapper 来获取数据,我已经在我的问题中包含了那部分代码,也供您参考...以便您全面了解代码..
    • 小巧的代码正在返回一个完整的数据集,所以请考虑我回复中的第一个通知
    • 由于我使用 Dapper 将 eNewsList = await NewsService.GetNews(1).Skip((P - 1) * S).Take(S).ToListAsync(); 工作,因为我在 Skip(... 上遇到错误可能与 EF 有关
    • 是的,您应该将分页记录的结果分配给eNewsList
    猜你喜欢
    • 2020-06-06
    • 2018-03-18
    • 2020-05-06
    • 2021-06-26
    • 2021-12-25
    • 2021-10-30
    • 2020-08-05
    • 2020-02-09
    • 1970-01-01
    相关资源
    最近更新 更多