基于存储过程的MVC开源分页控件
基于存储过程的MVC开源分页控件--LYB.NET.SPPager
摘要
现在基于ASP.NET MVC的分页控件我想大家都不陌生了,百度一下一大箩筐。其中有不少精品,陕北吴旗娃杨涛大哥做的分页控件MVCPager(http://www.webdiyer.com/)算作当下开源里面的佼佼者,曾经在使用过程中感觉效果非常棒,拜读其源码也受益非浅。于是写下LYB.NET.SPPager控件,并提交到CodePlex,希望大家多提意见。
项目源地址:https://lybpager.codeplex.com/
项目下载地址:https://lybpager.codeplex.com/releases 其中包括分页控件源码,演示工程,分页控件DLL
需要分析
在一般的网页开发中,在数据库中写通用分页存储过程,然后在WEB中调用是一种最常见的方法。于是基本这个大前提下,规划出以下需求:
- 1、控件可以实现有一个默认存储过程,无需客户端用户关心存储过程;
- 2、控件可以扩展支持用户自定义存储过程;
- 3、控件获取的数据列表以List<T>的形式传递给客户端,使用户不用去操作诸如SqlDataReader之类与数据库相关的东西;
- 4、完成前端页码导航;
客户端使用
最终调用效果(无样式表,纯天然的)
多页效果
客户调用代码说明
使用到的默认分页存储过程.LYBPager可以在演示项目根目录中找到。测试表数据结构如下:
1、建一个基于MVC3.0的网站。文件结构如下图所示:
2、控制器HomeController代码如下:

- using LYB.NET.SPPager;
- using LYB.NET.WEBTEST.Models;
- namespace LYB.NET.WEBTEST.Controllers
- {
- public class HomeController : Controller
- {
- public ActionResult Index(int? id)
- {
- string connection = "Data Source=玉宝;Initial Catalog=Shop;Integrated Security=True;Pooling=False";
- //采用默认LYBSPPager分页存储过程
- StoredProcedureBase sql = new LYBSPPager(connection)
- {
- TableName = "Products",
- PrimaryKey = "ProductId",
- SortField = "ProductId desc",
- OrderBy = 1
- };
- IRepository target = new SPRepository(sql);
- int pageindex = id ?? 1;
- var actual = target.GetList<Product>(pageindex, 5);
- if (Request.IsAjaxRequest())
- return PartialView("PageList", actual);
- return View(actual);
- }
- }
- }

3、查询的数据模型Product如下:

- using LYB.NET.SPPager;
- namespace LYB.NET.WEBTEST.Models
- {
- public class Product
- {
- [BindingFieldAttribute("ProductId")]
- public int ProductId { get; set; }
- [BindingFieldAttribute("ProductName")]
- public string ProductName { get; set; }
- }
- }

采用C#自定义的特性BindingFieldAttribute实现数据库字段与对象属性进行绑定,从而实现为具体的数据库操作分离;
4、主界面Index.cshtml如下:
- @using LYB.NET.SPPager
- @using LYB.NET.WEBTEST.Models
- @model PageList<Product><h2>Index</h2>
- @Html.Partial("PageList", Model)
5、分页列表PageList.cshtml(部分视图)代码如下:

- @using LYB.NET.SPPager
- @using LYB.NET.WEBTEST.Models
- @model PageList<Product>
- <div id = "mainpage">
- <table>
- <tr>
- <th>
- Product ID
- </th>
- <th>Product Name</th>
- </tr>
- @foreach (var item in Model) {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.ProductId)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.ProductName)
- </td>
- </tr>
- }
- </table>
- @Html.AjaxPager(Model, new PageOption { }, new AjaxOptions { UpdateTargetId="mainpage" })
- </div>

分页源码分析
源代码文件结构如下:
类图结构如下:
部分核心代码解释:
1、IPageList接口是参考杨涛大哥的MVCPager中的实现,能够为前端页码导航提供当前页码、总记录数、每页记录数待信息;
2、IRepository接口可以为将来控件扩展或用户自己扩展时,提供获取数据的接口,而不用改动WEB端调用代码;
3、StoredProcedureBase是个抽象基类,如果用户想使用自己的存储过程,只要继承这个类,并重写以下两个属性,然后添加自己想要的属性即可:
- public abstract class StoredProcedureBase
- {
- public abstract SqlParameter[] Parament { get; }
- public abstract int RecordCount { get; }
- }
可以参考我的默认LYBSPPager的写法:

- namespace LYB.NET.SPPager
- {
- ///<summary>
- ///<para>默认LYBPager存储过程</para>
- ///<para>[带*号为初始化时必须指定字段]</para>
- ///<para>*TableName --要显示的表或多个表的连接 </para>
- ///<para>*PrimaryKey --用于排序的主键 </para>
- ///<para>*SortField --用于排序,如:id desc (多个id desc,dt asc)</para>
- ///<para>QueryField --要查询出的字段列表,*表示全部字段 </para>
- ///<para>Where --查询条件,不需where </para>
- ///<para>OrderBy --排序,0-顺序,1-倒序,与SortField保持一致 </para>
- ///<para>RecordCount --查询到的总记录数[readonly] </para>
- /// </summary>
- public class LYBSPPager : StoredProcedureBase
- {
- public string TableName { get; set; }
- public string QueryField { get; set; }
- public string PrimaryKey { get; set; }
- public string SortField { get; set; }
- public string Where { get; set; }
- public int OrderBy { get; set; }
- public LYBSPPager(string strconn)
- : base(strconn, ".LYBPager") { }
- /// <param name="strconn">连接字符串名称</param>
- /// <param name="tablename">要显示的表或多个表的连接 </param>
- /// <param name="primarykey">主键</param>
- /// <param name="sortfield">用于排序,如:id desc (多个id desc,dt asc)</param>
- public LYBSPPager(string strconn, string tablename, string primarykey, string sortfield)
- : base(strconn, ".LYBPager")
- {
- TableName = tablename;
- PrimaryKey = primarykey;
- SortField = sortfield;
- }
- public override SqlParameter[] Parament
- {
- get
- {
- if (string.IsNullOrEmpty(TableName))
- throw new ApplicationException("LYBSPPager对象TableName属性不能为空");
- if (string.IsNullOrEmpty(PrimaryKey))
- throw new ApplicationException("LYBSPPager对象PrimaryKey属性不能为空");
- if (string.IsNullOrEmpty(SortField))
- throw new ApplicationException("LYBSPPager对象SortField属性不能为空");
- SqlParameter[] para = new SqlParameter[]{
- new SqlParameter("@strTable",SqlDbType.VarChar,-1),
- new SqlParameter("@strField",SqlDbType.VarChar,-1),
- new SqlParameter("@pageSize",SqlDbType.Int),
- new SqlParameter("@pageIndex",SqlDbType.Int),
- new SqlParameter("@strSortKey",SqlDbType.VarChar,-1),
- new SqlParameter("@strSortField",SqlDbType.VarChar,-1),
- new SqlParameter("@strOrderBy",SqlDbType.Bit),
- new SqlParameter("@RecordCount",SqlDbType.Int),
- new SqlParameter("@strWhere",SqlDbType.VarChar,-1)
- };
- para[0].Value = TableName;
- para[1].Value = QueryField;
- para[2].Value = PageSize;
- para[3].Value = CurrentPageIndex;
- para[4].Value = PrimaryKey;
- para[5].Value = SortField;
- para[6].Value = OrderBy;
- para[7].Direction = ParameterDirection.Output;
- para[8].Value = Where;
- return para;
- }
- }
- public override int RecordCount { get { return int.Parse(_command.Parameters["@RecordCount"].Value.ToString()); } }
- }
- }

总结
第一次写C#的DLL,代码中存在很多不完善的地方,还请志同道合的同仁一起帮忙。谢谢大家。
项目中存储过程用的是MAX的分页,在100W级数据测试下,速度还是非常快的。关于存储过程分页速度方面,有位兄弟已经做过类似总结:http://www.cnblogs.com/yangyy753/archive/2013/01/23/2872753.html
最后,说一下关于分页这个东西,在很多人看来,这是个很小的东西。看过有些弟兄的评论说:一个分页至于整的这么复杂吗?其实不怕各位高手笑话,我以前分页确实都是直接写的,方便,快速,后来发现每次都要自己重新写。做了很多重复的工作。直到用了杨涛大哥的分页,才告别这种COPY代码的生活。
---工作也有好几年了,做过ASP,弄过嵌入式开发,写过单片机,整过无线通信协议,该静下心来了,为了自己的事业,加油!!
基于存储过程的MVC开源分页控件的更多相关文章
- 基于存储过程的MVC开源分页控件--LYB.NET.SPPager
摘要 现在基于ASP.NET MVC的分页控件我想大家都不陌生了,百度一下一大箩筐.其中有不少精品,陕北吴旗娃杨涛大哥做的分页控件MVCPager(http://www.webdiyer.com/)算 ...
- 基于KO+bootstrap+MVC的分页控件
JS: /// <reference path="../knockout-3.2.0.js" /> var ViewModel = function (data) { ...
- 基于Bootstrap仿淘宝分页控件实现
.header { cursor: pointer } p { margin: 3px 6px } th { background: lightblue; width: 20% } table { t ...
- MvcPager 免费开源分页控件3.0版发布!
MvcPager 3.0版在原2.0版的基础上进行了较大的升级,对MvcPager脚本插件重写并进行了大量优化.修复了部分bug并新增了客户端Javascript API等功能,使用更方便,功能更强大 ...
- Mvc自定义分页控件
MVC开发分页常常使用第三方控件,生成的分页HTML带有版权申明,虽然免费,但是总有的别扭.于是,某日,楼主闲来蛋疼,折腾了个自定义分页控件: 先来展示下效果图: 1>当分页不超过10页的时候, ...
- Net MVC轻量级分页控件
JPager.Net MVC超好用轻量级分页控件 JPager.Net MVC好用的轻量级分页控件,好用到你无法想象,轻量到你无法想象. JPager.Net MVC好用的轻量级分页控件,实现 ...
- 基于jquery扩展漂亮的分页控件(ajax)
分页控件式大家在熟悉不过的控件,很多情况下都需要使用到分页控件来完成列表数据加载操作,在很多分页控件中有的编写麻烦,有的应用扩展比较复杂,有的分页控件样式比较丑陋,有的分页控件用户体验操作比较简单等等 ...
- 基于C#语言MVC框架NPOI控件导出Excel表数据
控件bin文件下载地址:https://download.csdn.net/download/u012949335/10610726@{ ViewBag.Title = "dcxx" ...
- MVC Page分页控件
MVCPage帮助类 控制器代码 public ActionResult Article(int? page) { //Session["ArticleClass"] = cont ...
随机推荐
- .Net2.0 --Winform结合WebBrowser控件和Socket老技术来实现另类Push~
原文:.Net2.0 --Winform结合WebBrowser控件和Socket老技术来实现另类Push~ 目前的企业级开发比较流行的是Web2.0技术,但是由于Web技术基于请求--响应的交互模式 ...
- tinyxml 查找element
下面这段代码是网上找来的,很是经典 bool GetNodePointerByName(TiXmlElement* pRootEle, const char* strNodeName,TiXmlEle ...
- AngularJS系列之总结
AngularJS深入的系列就是这九篇博客了,把我以前在项目中应用到的和自己学习的都总结在了里面.为了更方便的看,把我写的AngularJS系列的博客都列到下面.之后就开始学习ionic:html5移 ...
- Hack 语言学习/参考---1.2 Hack Background
Hack Background Facebook was initially built with PHP. Parameters and return types were specified in ...
- MVC 5 Scaffolding多层架构代码生成向导开源项目
asp.net MVC 5 Scaffolding多层架构代码生成向导开源项目(邀请你的参与) Visual Studio.net 2013 asp.net MVC 5 Scaffolding代码 ...
- vim打开出现的文档^M什么
网上公开的一些代码,发现里面多^M符号.这是什么? 我搜索^M没有效果,这应该是一个特殊的控制字符.找换行的结果是不.在每一行的末尾是回车,代替它周围包裹,对于由线定义不同的编码系统是不一样的. li ...
- WEB开发中常用的正则表达式集合
在计算机科学中,正则表达式用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串.在WEB开发中,正则表达式通常用来检测.查找替换某些符合规则的字符串,如检测用户输入E-mai格式是否正确,采集符 ...
- Goldeneye.py网站压力测试工具2.1版源码
Goldeneye压力测试工具的源代码,粗略看了下,代码写的蛮规范和易读的,打算边读边加上了中文注释,但是想来也没太大必要,代码600多行,值得学习的地方还是蛮多的,喜欢Python的同学可以一读 这 ...
- 我的vi/vim配置文件
位于/etc/vim/的vimrc " All system-wide defaults are set in $VIMRUNTIME/debian.vim and sourced by & ...
- VMWare 11安装操作系统 - 初学者系列 - 学习者系列文章
在2010年的时候,我写过一篇关于VMWare的安装操作系统的博文.但是今天在QQ群里有人问起VMWare安装操作系统的问题,虽然回答了,但是回头看了下当时那篇博文,决定重新写一文. 首先要获取VMW ...