您的位置:首页 > 编程语言 > ASP

ASP.NET MVC分页的实现(上)

2009-09-08 22:10 519 查看
在ASP.NET中,GridView控件本身就带有分页的功能,只要把当前页面的索引值赋给GridView的PageIndex就可以实现了分页,至于数据怎么分页,全都由GridView封装起来了。
在ASP.NET MVC中分页的实现就只能靠自己来设计了。首先来说一下分页的原理。现在有一个张news表,中间有很多信息,我们假设一页显示5条记录,这样,页面数量=总记录数/5;这里,如果出现小数,得进位取整。如比总记录和数为51,那么分的页面数量是11,最后一页只有一条记录。好,有这样一个思路后,现在就来做ASP.NET MVC中的分页了。
1、 数据库和表
创建一个Data_Company的数据库,建一张news表,表结构如下图:




ID是主键,并助是自动增长列。
2、 现在,我们用O/R Designer来创建news表的LINQ To SQL的实体类。
创建一个名为MvcCompany的ASP.NET MVC Web Application项目,然后选中Models,右键,“添加”,“新建项”,选中C#中的“数据”,如下图:



选择“LINQ to SQL类”,名称设为“CompanyData.dbml”,然后“添加”。
打开“服务器资源管理器”,创建连接,展开表,找到news表,拖到CompanyData.dbml的左边表视图区(注:.dbml视图左边是SQL表和SQL视图区,右边是SQL存储过程和SQL函数区),效果如下图:



在“解决方案资源管理器”下的,“Models”多了三个文件,CompanyData.dbml,展开它,会有CompanyData.dbml.layout和CompanyData.designer.cs,前者是CompanyData.dbml视图的一些信息(比如news表在的坐标等信息),后者是news实体类及Data_Company数据库的类,在数据库类中聚合了news实体类。
3、 添加news列表类。因为一个news实体类,一次只能表示一条记录,如果呈现一个news表中的数据,最好定义一个集合类来存临时来存放news记录的集合。
类的实现如下:
[align=left]using System;[/align]
[align=left]using System.Collections.Generic;[/align]
[align=left]using System.Linq;[/align]
[align=left]using System.Web;[/align]
[align=left] [/align]
[align=left]namespace MvcCompany.Models[/align]
[align=left]{[/align]
[align=left] public class NewList<T> : List<T>[/align]
[align=left] {[/align]
[align=left] /// <summary>[/align]
[align=left] /// 页面索引值[/align]
[align=left] /// </summary>[/align]
[align=left] public int PageIndex { get; private set; }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 每页记录的数量[/align]
[align=left] /// </summary>[/align]
[align=left] public int PageSize { get; private set; }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 记录总条数[/align]
[align=left] /// </summary>[/align]
[align=left] public int TotalCount { get; private set; }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 共有的页数和[/align]
[align=left] /// </summary>[/align]
[align=left] public int TotalPages { get; private set; }[/align]
[align=left] [/align]
[align=left] public NewList(IQueryable<T> source, int pageIndex, int pageSize)[/align]
[align=left] {[/align]
[align=left] PageIndex = pageIndex;[/align]
[align=left] PageSize = pageSize;[/align]
[align=left] TotalCount = source.Count();[/align]
[align=left] // 进上去取整( 总记录条数/一面记录的条数)[/align]
[align=left] TotalPages = (int)Math.Ceiling(TotalCount / (double)pageSize); [/align]
[align=left] this.AddRange(source.Skip(pageIndex * pageSize).Take(PageSize));[/align]
[align=left] }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 是否存在前续页[/align]
[align=left] /// </summary>[/align]
[align=left] public bool HasPreviousPage[/align]
[align=left] {[/align]
[align=left] get { return (PageIndex > 0); }[/align]
[align=left] }[/align]
[align=left] /// <summary>[/align]
[align=left] /// 是否存在后续页[/align]
[align=left] /// </summary>[/align]
[align=left] public bool HasNextPage[/align]
[align=left] {[/align]
[align=left] get { return (PageIndex + 1 < AllPages); }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
这里,我们实现了一个泛型的集合列表NewList(当然,这里的本质上可以当其他实体类的集合列表),在这个类中间,有四个字段,访问修饰符都是public的,分另为:
PageIndex:当前页面的索引值
PageSize:每个页面的记录的条数
AllCount:记录的总条数
AllPages:共有的页面总数
[align=left] [/align]
[align=left]在NewList 构造函数中,有如下代码:[/align]
[align=left]public NewList(IQueryable<T> list, int pageIndex, int pageSize)[/align]
[align=left]{[/align]
[align=left]1 PageIndex = pageIndex;[/align]
[align=left] 2 PageSize = pageSize;[/align]
[align=left] 3 AllCount = source.Count(); [/align]
[align=left] 4 AllPages = (int)Math.Ceiling(AllCount / (double)pageSize);[/align]
[align=left] 5 this.AddRange(list.Skip(PageIndex * PageSize).Take(PageSize));[/align]
}
构造函的参数有三个,一个是list,就是实体类的一个集合,还有就是页面索引值和每个页面的记录条数。
第1、2代码很容易理角,第3行代码是得到列表的总记录条数,第4行代码,就完成了我们在开始时分析的分页实现的公式:页面数量=总记录数/每页记录数,其中Math.Ceiling就是把小数部分进到整数的函数。
最关键的是第5行代码,首先看Skip(PageIndex*PageSize),页面索引值乘上每页记录数,得到是当前页面以前的所有记录数,Skip是跳过这些记录,而得到后面的所有记录,Take(PageSize)是得到PageSize条数的记录,比如,我们想要第三页的记录,这个页面的索引值为2(因为索引值从0开始)PageIndex=2,每页显示5条记录,PageSize=5,就是要跳过list中的前10条记录,然后再取前5条记录,即取list中的第11条到第15条记录,也就是第3页的记录了。
在这里,微软提供了Skip和Tabke函数,让我们做起分页来,得心应手。
接下来是this.AddRange()函数,可以把批量的数据放到当前集合中(因为NewList本身就是一个集合)。
代码的后半部分是两个属性:
[align=left] public bool HasPreviousPage[/align]
[align=left] {[/align]
[align=left] get { return (PageIndex > 0); }[/align]
[align=left] }[/align]
[align=left] public bool HasNextPage[/align]
[align=left] {[/align]
[align=left] get { return (PageIndex + 1 < AllPages); }[/align]
[align=left] }[/align]
[align=left]这两个属性是为页面显示“上一页”和“下一页”,因为当我们显示第一页的时候,“上一页”是不需要显示的,如果最后一页,是没有“下一页“的,所以在这里定义了两个属性,来判断是否有上一页和下一页。[/align]
[align=left]先看HasPreviousPage属性,如果PageIndex是大于0的,说明不是在第一页,所以就反回true,如果小于等于0(在这里小于0是没有意思义的,因为页面的索引值最小是0),说明是第一页,所以返回是false。[/align]
[align=left]再看HasNextPage属性,因为页面索引值的最大数,与页面的最大数差1(索引从0开始的原因),所以当PageIndex+1小于AllPages时,说没有没到最后一页,返回值是true,如果PageIndex+1大于等于AllPages时(大于也没有意义),说明是最后一页,返回值为false。[/align]
[align=left]4、 添加NewsController。选中Controller,右键添加一个NewsController 的Controller。[/align]
[align=left]代码如下:[/align]
[align=left]using System;[/align]
[align=left]using System.Collections.Generic;[/align]
[align=left]using System.Linq;[/align]
[align=left]using System.Web;[/align]
[align=left]using System.Web.Mvc;[/align]
[align=left]using System.Web.Mvc.Ajax;[/align]
[align=left]using MvcCompany.Models;[/align]
[align=left]using System.Configuration;[/align]
[align=left]namespace MvcCompany.Controllers[/align]
[align=left]{[/align]
[align=left] public class NewsController : Controller[/align]
[align=left] { [/align]
[align=left] DataClassesDataContext DCDC;[/align]
[align=left] int pageSize;[/align]
[align=left] public NewsController()[/align]
[align=left] {[/align]
[align=left] DCDC = new DataClassesDataContext();[/align]
[align=left] pageSize = Convert.ToInt32(ConfigurationManager.AppSettings["pagesize"]); //每个页面的数量存放在web.config的appsetting里的pagesize节中,值为5[/align]
[align=left] }[/align]
[align=left] public ActionResult Index(int? page)[/align]
[align=left] { [/align]
[align=left] var NewsList = DCDC.news.Select(newss=>newss);[/align]
[align=left] var paginatedNews = new NewList<news>(NewsList, page ?? 0, pageSize); //实现分页功能[/align]
[align=left] return View(paginatedNews);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [AcceptVerbs(HttpVerbs.Post)][/align]
[align=left] public ActionResult Index(FormCollection formValues)[/align]
[align=left] { [/align]
[align=left] int? index = int.Parse(formValues.GetValue("pageindex").AttemptedValue);[/align]
[align=left] int page = index ??0 ; [/align]
[align=left] var NewsList = DCDC.news.Select(newss => newss);[/align]
[align=left] var paginatedNews = new NewList<news>(NewsList, page, pageSize); //实现分页功能[/align]
[align=left] return View(paginatedNews);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]关于两个Index重载,我们在设计完Views再讨论。[/align]本文出自 “桂素伟” 博客,请务必保留此出处http://axzxs.blog.51cto.com/730810/200134
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: