ASP.NET MVC基于dapper的通用万能的泛型分页实例

这前做的一个mvc的文章系统用到分页,因为系统比较简单只涉及到一个表,文章的表的分页。最近的项目表比较多,所以我就写了一个通用万能的泛型mvc分页,用的dapper框架。dapper可以快速的用sql查询映射到我们需要的Model对象或者List集合对象,性能很不错,爱上它根本停不下来。因为我的视图要用强类型Model来绑定,所以想到了定义一个返回泛型的分页方法。

1、定义一个用来装载适合所有类的分页结果类

 
  1. public class PageDataView<T>
  2. {
  3. private int _TotalNum;
  4. public PageDataView()
  5. {
  6. this._Items = new List<T>();
  7. }
  8. public int TotalNum
  9. {
  10. get { return _TotalNum; }
  11. set { _TotalNum = value; }
  12. }
  13. private IList<T> _Items;
  14. public IList<T> Items
  15. {
  16. get { return _Items; }
  17. set { _Items = value; }
  18. }
  19. public int CurrentPage { get; set; }
  20. public int TotalPageCount { get; set; }
  21. }

PageDataView的Items一个泛型属性,所以可以适合所有的类,简洁而通用。

2、定义一个通用的获取分页数据的类

上面是通过用dapper调用sql server的分页存储过程返回数据了。ProcGetPageData就是通用的分页存储过程,之前我写,最通用的ibatis.Net使用sql server存储过程返回分页数据的详细例子也用的是这个存储过程,现在再把这个存储过程放出来:

 
  1. Create PROCEDURE [dbo].[ProcGetPageData]
  2. (  @TableName VARCHAR(1000), --表名,多表是请使用 tA a inner join tB b On a.AID = b.AID
  3.    @PrimaryKey NVARCHAR(100),    --主键,可以带表头 a.AID
  4.    @Fields NVARCHAR(2000) = '*',--读取字段
  5.    @Condition NVARCHAR(3000) = '',--Where条件
  6.    @CurrentPage INT = 1,    --开始页码
  7.    @PageSize INT = 10,        --页大小
  8.    @Sort NVARCHAR(200) = '', --排序字段
  9.    @RecordCount INT = 0 OUT
  10. )
  11. AS
  12. DECLARE @strWhere VARCHAR(2000)
  13. DECLARE @strsql NVARCHAR(3900)
  14. IF @Condition IS NOT NULL AND len(ltrim(rtrim(@Condition)))>0
  15.   BEGIN
  16.    SET @strWhere = ' WHERE ' + @Condition + ' '
  17.   END
  18. ELSE
  19.   BEGIN
  20.    SET @strWhere = ''
  21.   END
  22.         
  23. IF (charindex(ltrim(rtrim(@PrimaryKey)),@Sort)=0)
  24. BEGIN
  25.     IF(@Sort='')
  26.         SET @Sort = @PrimaryKey + ' DESC '
  27.     ELSE
  28.         SET @Sort = @Sort+ ' , '+@PrimaryKey + ' DESC '
  29. END
  30. SET @strsql = 'SELECT @RecordCount = Count(1) FROM ' + @TableName + @strWhere  
  31. EXECUTE sp_executesql @strsql ,N'@RecordCount INT output',@RecordCount OUTPUT
  32. IF @CurrentPage = 1 --第一页提高性能
  33. BEGIN 
  34.   SET @strsql = 'SELECT TOP ' + str(@PageSize) +' '+@Fields
  35.               + '  FROM ' + @TableName + ' ' + @strWhere + ' ORDER BY  '+ @Sort
  36. END 
  37. ELSE
  38.   BEGIN
  39.     /* Execute dynamic query */    
  40.     DECLARE @START_ID NVARCHAR(50)
  41.     DECLARE @END_ID NVARCHAR(50)
  42.     SET @START_ID = CONVERT(NVARCHAR(50),(@CurrentPage - 1) * @PageSize + 1)
  43.     SET @END_ID = CONVERT(NVARCHAR(50),@CurrentPage * @PageSize)
  44.     SET @strsql =  ' SELECT *
  45.    FROM (SELECT ROW_NUMBER() OVER(ORDER BY '+@Sort+') AS rownum, 
  46.      '+@Fields+ '
  47.       FROM '+@TableName + @strWhere +') AS XX
  48.    WHERE rownum BETWEEN '+@START_ID+' AND ' +@END_ID +' ORDER BY XX.rownum ASC'
  49.   END
  50. EXEC(@strsql)
  51. RETURN

3、获取分页数据

调用分页存储过程的公共类:

 
  1. public class Common
  2. {
  3. public static string DBConnString = System.Configuration.ConfigurationManager.ConnectionStrings["DBContext"].ConnectionString;
  4. public static System.Data.IDbConnection GetConn()
  5. {
  6. return new System.Data.SqlClient.SqlConnection(Common.DBConnString);
  7. }
  8. public static PageDataView<T> GetPageData<T>(PageCriteria criteria,object param=null)
  9. {
  10. using (var conn = Common.GetConn())
  11. {
  12. var p = new DynamicParameters();
  13. string proName = "ProcGetPageData";
  14. p.Add("TableName", criteria.TableName);
  15. p.Add("PrimaryKey", criteria.PrimaryKey);
  16. p.Add("Fields", criteria.Fields);
  17. p.Add("Condition", criteria.Condition);
  18. p.Add("CurrentPage", criteria.CurrentPage);
  19. p.Add("PageSize", criteria.PageSize);
  20. p.Add("Sort", criteria.Sort);
  21. p.Add("RecordCount", dbType: DbType.Int32, direction: ParameterDirection.Output);
  22. conn.Open();
  23. var pageData = new PageDataView<T>();
  24. pageData.Items = conn.Query<T>(proName, p, commandType: CommandType.StoredProcedure).ToList();
  25. conn.Close();
  26. pageData.TotalNum = p.Get<int>("RecordCount");
  27. pageData.TotalPageCount = Convert.ToInt32(Math.Ceiling(pageData.TotalNum * 1.0 / criteria.PageSize));
  28. pageData.CurrentPage = criteria.CurrentPage > pageData.TotalPageCount ? pageData.TotalPageCount : criteria.CurrentPage;
  29. return pageData;
  30. }
  31. }
  32. }

上面用到ProcGetPageData存储过程和dapper的动态参数DynamicParameters,用的泛型conn.Query<T>方法,这样可以适应所有的返回类型,最大的达到的代码的简洁和重用。

下面是dapper通用万能的泛型分页公共类的使用方法:

 
  1. public static PageDataView<MSys_Admin> GetList(string name, string loginName, int page,int pageSize=10)
  2. {
  3. PageCriteria criteria = new PageCriteria();
  4. criteria.Condition = "1=1";
  5. if (!string.IsNullOrEmpty(name))
  6. criteria.Condition += string.Format(" and Name like '%{0}%'", name);
  7. if (!string.IsNullOrEmpty(loginName))
  8. criteria.Condition += string.Format(" and LoginName like '%{0}%'", loginName);
  9. criteria.CurrentPage = page;
  10. criteria.Fields = "*";
  11. criteria.PageSize = pageSize;
  12. criteria.TableName = "Sys_Admin a";
  13. criteria.PrimaryKey = "UID";
  14. var r = Common.GetPageData<MSys_Admin>(criteria);
  15. return r;
  16. }

PageCriteria是一个封装查询条件相关信息的类。

 
  1. public class PageCriteria
  2. {
  3. private string _TableName;
  4. public string TableName
  5. {
  6. get { return _TableName; }
  7. set { _TableName = value; }
  8. }
  9. private string _Fileds = "*";
  10. public string Fields
  11. {
  12. get { return _Fileds; }
  13. set { _Fileds = value; }
  14. }
  15. private string _PrimaryKey = "ID";
  16. public string PrimaryKey
  17. {
  18. get { return _PrimaryKey; }
  19. set { _PrimaryKey = value; }
  20. }
  21. private int _PageSize = 10;
  22. public int PageSize
  23. {
  24. get { return _PageSize; }
  25. set { _PageSize = value; }
  26. }
  27. private int _CurrentPage = 1;
  28. public int CurrentPage
  29. {
  30. get { return _CurrentPage; }
  31. set { _CurrentPage = value; }
  32. }
  33. private string _Sort = string.Empty;
  34. public string Sort
  35. {
  36. get { return _Sort; }
  37. set { _Sort = value; }
  38. }
  39. private string _Condition = string.Empty;
  40. public string Condition
  41. {
  42. get { return _Condition; }
  43. set { _Condition = value; }
  44. }
  45. private int _RecordCount;
  46. public int RecordCount
  47. {
  48. get { return _RecordCount; }
  49. set { _RecordCount = value; }
  50. }
  51. }

GetList调用了Common的GetPageData返回分页数据,这里用了一个表,Sys_Admin表数据如下图:

注意:GetList的参数name和loginName是直接拼接到sql里面,有sql注入的风险,我会在接下来的文章中来解决这个问题。

4、视图绑定

视图文件的头部加上:

@model PageDataView<MSys_Admin>

表示这个视图是model类型是PageDataView<MSys_Admin>类型,分页里面的具体类是MSys_Admin。

绑定数据:

 
  1. <table cellspacing="1" cellpadding="3" class="tablehead" style="background:#CCC;">
  2. <thead>
  3. <tr>
  4. <th align="center">名称</th>
  5. <th align="center">登录名</th>
  6. <th align="center">添加时间</th>
  7. <th align="center">操作</th>
  8. </tr>
  9. </thead>
  10. <tbody>
  11. @if (Model != null)
  12. {
  13. foreach (var item in Model.Items)
  14. {
  15. <tr>
  16. <td align="center">@item.Name</td>
  17. <td align="center">@item.LoginName</td>
  18. <td align="center">@item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")</td>
  19. <td align="center">
  20. <form method="post" action="@Url.Action("Delete")">
  21. <input type="hidden" name="UID" value="@item.UID" />
  22. <input type="submit" οnclick="return confirm('确定要删除吗?')" value="删除" class="btn" />
  23. <a href="@Url.Action("Edit", new {ID=item.UID })" class="add">修改</a>&nbsp;&nbsp;
  24. </form>
  25. </td>
  26. </tr>
  27. }
  28. }
  29. </tbody>
  30. </table>
  31. <!--tab end-->
  32. <div class="pagination">
  33. @Html.PageLinks(Model, p => string.Format("/Admin?name={0}&loginName={1}&page={2}", ViewBag.Name,@ViewBag.LoginName, p), 10)
  34. </div>

说明:Html.PageLinks是我写的一个使用扩展方法实现的通用mvc分页组件,是用来生成分页的页码导航的。

.net网站&系统开发技术学习交流群:533829726

本站文章除注明转载外,均为本站原创或翻译,欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,共创和谐网络环境。
转载请注明:文章转载自:蓝狐软件工作室 » 原创--ASP.NET MVC基于dapper的通用万能的泛型分页实例
本文标题:原创--ASP.NET MVC基于dapper的通用万能的泛型分页实例
本文地址:http://www.lanhusoft.com/Article/130.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值