zoukankan      html  css  js  c++  java
  • 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](十一)

    前言

    小伙伴们,
    大家好,我是Rector。
    最近Rector忙于换工作,没有太多时间来更新我们的ASP.NET MVC 5系列文章 [一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar],直到现在才挤些时间赶紧更新一篇,小伙伴们等得太久了。

    写系列文章是一件并不容易的事情,相信有过写系列文章经验朋友也应该有所体会。

    本文知识要点

    本期是该系列的第十一篇,上一篇《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](十)》我们了解了母版页和部分视图,并使用母版页和部分视图重新组织了页面的共用区域的HTML代码,本文我们将要涉及到的内容为:

    • 通用分页的封装
    • 文章分页的实现

    通用分页的封装

    在之前两期中,我们的文章列表页面是没有分页功能的,而是使用如下方法:

    public IEnumerable<Post> FindHomePagePosts(int limit = 20)
            {
                using (var db = DbFactory.GetSqlSugarClient())
                {
                    var list = db.Queryable<Post>().OrderBy(x => x.Id, OrderByType.Desc).Take(limit).ToList();
                    return list;
                }
            }
    

    来读取文章表中的前N(20)条记录作为首页的文章列表数据源。那么,本文将为大家封装一个通用的分页信息类以及分页泛型方法,并最终实现首页文章列表的数据分页功能。分页效果如下图:

    一步一步创建ASP.NET MVC5程序Repository+Autofac+Automapper+SqlSugar

    创建IPagedList接口及实现

    打开项目TsBlog.Repositories,在此项目中分别新建两个类:IPagedList.csPagedList.cs,代码分别如下:

    IPagedList.cs

    using System.Collections.Generic;
    
    namespace TsBlog.Repositories
    {
        public interface IPagedList<T> : IList<T>
        {
            int PageIndex { get; }
            int PageSize { get; }
            int TotalCount { get; }
            int TotalPages { get; }
            bool HasPreviousPage { get; }
            bool HasNextPage { get; }
        }
    }
    

    IPagedLIst.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace TsBlog.Repositories
    {
        /// <summary>
        /// 分页组件实体类
        /// </summary>
        /// <typeparam name="T">泛型实体</typeparam>
    
        [Serializable]
        public class PagedList<T> : List<T>, IPagedList<T>
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="source">数据源</param>
            /// <param name="pageIndex">分页索引</param>
            /// <param name="pageSize">分页大小</param>
            public PagedList(IQueryable<T> source, int pageIndex, int pageSize)
            {
                var total = source.Count();
                TotalCount = total;
                TotalPages = total / pageSize;
    
                if (total % pageSize > 0)
                    TotalPages++;
    
                PageSize = pageSize;
                PageIndex = pageIndex;
    
                AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());
            }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="source">数据源</param>
            /// <param name="pageIndex">分页索引</param>
            /// <param name="pageSize">分页大小</param>
            public PagedList(IList<T> source, int pageIndex, int pageSize)
            {
                TotalCount = source.Count();
                TotalPages = TotalCount / pageSize;
    
                if (TotalCount % pageSize > 0)
                    TotalPages++;
    
                PageSize = pageSize;
                PageIndex = pageIndex;
                AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());
            }
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="source">数据源</param>
            /// <param name="pageIndex">分页索引</param>
            /// <param name="pageSize">分页大小</param>
            /// <param name="totalCount">总记录数</param>
            public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
            {
                TotalCount = totalCount;
                TotalPages = TotalCount / pageSize;
    
                if (TotalCount % pageSize > 0)
                    TotalPages++;
    
                PageSize = pageSize;
                PageIndex = pageIndex;
                AddRange(source);
            }
    
            /// <summary>
            /// 分页索引
            /// </summary>
            public int PageIndex { get; }
            /// <summary>
            /// 分页大小
            /// </summary>
            public int PageSize { get; private set; }
            /// <summary>
            /// 总记录数
            /// </summary>
            public int TotalCount { get; }
            /// <summary>
            /// 总页数
            /// </summary>
            public int TotalPages { get; }
    
            /// <summary>
            /// 是否有上一页
            /// </summary>
            public bool HasPreviousPage
            {
                get { return (PageIndex > 0); }
            }
            /// <summary>
            /// 是否有下一页
            /// </summary>
            public bool HasNextPage
            {
                get { return (PageIndex + 1 < TotalPages); }
            }
        }
    }
    

    其中,IPagedList.cs为一个分页信息接口,包含了分页的基本信息,如:当前页索引(PageIndex),分页大小(PageSize),总记录数(TotalCount),总页数(TotalPages)等等。而PagedList.cs类文件则是对IPagedList.cs接口的实现。

    添加泛型仓储分页接口

    打开项目TsBlog.RepositoriesIRepository.cs 文件,在其中新建分页接口,如下:

    /// <summary>
    /// 根据条件查询分页数据
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="orderBy"></param>
    /// <param name="pageIndex">当前页面索引</param>
    /// <param name="pageSize">分布大小</param>
    /// <returns></returns>
    IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20);
    

    再打开此项目中的 GenericRepository.cs 泛型仓储实现类,在其中实现FindPagedList这个分页方法,如下:

    /// <summary>
    /// 根据条件查询分页数据
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="orderBy"></param>
    /// <param name="pageIndex">当前页面索引</param>
    /// <param name="pageSize">分布大小</param>
    /// <returns></returns>
    public IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20)
    {
        using (var db = DbFactory.GetSqlSugarClient())
        {
            var totalCount = 0;
            var page = db.Queryable<T>().OrderBy(orderBy).ToPageList(pageIndex, pageSize, ref totalCount);
            var list = new PagedList<T>(page, pageIndex, pageSize, totalCount);
            return list;
        }
    }
    

    类似地操作,打开项目 TsBlog.Services,并打开文件 IService.cs,在其中添加分页服务接口,如下:

    /// <summary>
    /// 根据条件查询分页数据
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="orderBy"></param>
    /// <param name="pageIndex">当前页面索引</param>
    /// <param name="pageSize">分布大小</param>
    /// <returns></returns>
    IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20);
    

    再打开此项目中的泛型服务类GenericService.cs,在其中实现分页服务接口,如下:

    /// <summary>
    /// 根据条件查询分页数据
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="orderBy"></param>
    /// <param name="pageIndex">当前页面索引</param>
    /// <param name="pageSize">分布大小</param>
    /// <returns></returns>
    public IPagedList<T> FindPagedList(Expression<Func<T, bool>> predicate, string orderBy = "", int pageIndex = 1, int pageSize = 20)
    {
        return _repository.FindPagedList(predicate, orderBy, pageIndex, pageSize);
    }
    

    到此,我们的泛型仓储和服务的通用分页接口和实现就封装完成了,现在我们需要使用以上的分页封装,在UI层来实现文章列表的分页功能。

    **切换到项目 TsBlog.Frontend **。

    安装第三方分页组件

    为了方便,本示例教程使用的是第三方的分页组件来实现UI层的分页功能,组件为:PagedList。安装的方式为:nuget,所以与以前几期的nuget包安装类似,打开nuget包管理工具,搜索关键词PagedList,在查询出来的包中,选择PagedList.MvcPagedList两个分页组件包并安装,如下:

    分页组件安装完成之后,我们再打开 HomeController 控制器,修改Index这个ActionHomerController.cs修改后的完整代码如下:

    using PagedList;
    using System.Linq;
    using System.Web.Mvc;
    using TsBlog.AutoMapperConfig;
    using TsBlog.Frontend.Extensions;
    using TsBlog.Services;
    using TsBlog.ViewModel.Post;
    
    namespace TsBlog.Frontend.Controllers
    {
        public class HomeController : Controller
        {
            /// <summary>
            /// 文章服务接口
            /// </summary>
            private readonly IPostService _postService;
            public HomeController(IPostService postService)
            {
                _postService = postService;
            }
            /// <summary>
            /// 首页
            /// </summary>
            /// <returns></returns>
            public ActionResult Index(int? page)
            {
                //var list = _postService.FindHomePagePosts();
                //读取分页数据,返回IPagedList<Post>
                page = page ?? 0;
                var list = _postService.FindPagedList(x => !x.IsDeleted && x.AllowShow, pageIndex: (int)page, pageSize: 10);
                var model = list.Select(x => x.ToModel().FormatPostViewModel());
                ViewBag.Pagination = new StaticPagedList<PostViewModel>(model, list.PageIndex, list.PageSize, list.TotalCount);
                return View(model);
            }
        }
    }
    

    最后,再打开Index对应的视图文件:/Views/Home/Index.cshtml,添加分页控件,如下:

    @using PagedList
    @using PagedList.Mvc
    @model IEnumerable<TsBlog.ViewModel.Post.PostViewModel>
    @{
        Layout = "~/Views/Shared/_Layout.cshtml";
        ViewBag.Title = "ASP.NET MVC 5 系列文章教程--首页";
    }
    <div class="jumbotron">
        <h1>小伙伴,你好</h1>
        <p>欢迎来到 Rector 的ASP.NET MVC 5 系列文章教程。在这里,Rector将和你一起一步一步创建一个集成Repository+Autofac+Automapper+SqlSugar的WEB应用程序。</p>
        <p>你准备好了吗?</p>
        <p>......</p>
        <p>让我们开始ASP.NET MVC 5 应用程序的探索之旅吧!!!</p>
    </div>
    <strong class="post-title">文章列表(@(Model.Count())篇)</strong>
    <ul class="list-unstyled post-item-box">
        @foreach (var p in Model)
        {
            <li>
                <h2><a href="~/post/details/@p.Id">@p.Title</a></h2>
                <p class="post-item-summary">@p.Summary ... <a href="~/post/details/@p.Id">阅读全文</a></p>
            </li>
        }
    </ul>
    @Html.PagedListPager((IPagedList)ViewBag.Pagination, page => Url.Action("index", new { page }), new PagedListRenderOptions
    {
        LinkToFirstPageFormat = "首页",
        LinkToPreviousPageFormat = "上一页",
        LinkToNextPageFormat = "下一页",
        LinkToLastPageFormat = "末页",
        DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded,
        DisplayLinkToLastPage = PagedListDisplayMode.Never,
        DisplayEllipsesWhenNotShowingAllPageNumbers = true,
        MaximumPageNumbersToDisplay = 5
    })
    

    以上所有更改完成后,就完成了我们对通用分页的封装和实现,当然,这个通用分页是非常简单的,只能满足单表数据的分页查询和读取。更复杂的分页需求请自行根据思路进行实现。

    完成以上步骤之后,我们重新编译和生成项目 TsBlog.Frontend 。最后,在浏览器中打开地址: http://localhost:54739/ ,检查一下,数据分页功能是否起作用了呢?

    好了,如果你喜欢Rector,或者是喜欢本系列文章,请为我点个赞,以鼓励Rectro继续写出更好的文章,或者系列文章。

    本期源码托管地址:请至首发地址《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](十一)》查看

    看完教程如果觉得还不过瘾的,想“勾对”的,欢迎加入图享网官方QQ群:483350228,如果你按照教程还原出来的程序运行有问题,请参照本期源码对应调整与修改遇到问题的,也欢迎加入QQ群。有什么,你懂的。。。_

    谢谢你的耐心阅读,本系列未完待续,我们下期再见……

    同时,也欢迎大家关注我们的.NET编程爱好者社区:https://2sharings.com 每天都有.NET的开发技术干货更新哦。

    [https://2sharings.com] 一个.NET编程爱好者社区,专注.NET/C#开发,帮助你找到疑难问题的更优美、更高级的解决方案

  • 相关阅读:
    初探JavaScript(一)——也谈元素节点、属性节点、文本节点
    解决Myeclipse下Debug出现Source not found以及sql server中导入数据报错
    Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable
    Hadoop阅读笔记(五)——重返Hadoop目录结构
    Hadoop阅读笔记(四)——一幅图看透MapReduce机制
    可视化(番外篇)——在Eclipse RCP中玩转OpenGL
    可视化(番外篇)——SWT总结
    Hadoop阅读笔记(三)——深入MapReduce排序和单表连接
    探秘Tomcat(一)——Myeclipse中导入Tomcat源码
    osgearth将视点绑定到一个节点上
  • 原文地址:https://www.cnblogs.com/bobositlife/p/8565806.html
Copyright © 2011-2022 走看看