最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

基于Dapper实现分页效果 支持筛选、排序、结果集总数等

来源:动视网 责编:小采 时间:2020-11-27 22:35:31
文档

基于Dapper实现分页效果 支持筛选、排序、结果集总数等

基于Dapper实现分页效果 支持筛选、排序、结果集总数等:简介 之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护。 代码 首先先上代码: https://github.com/jinweijie/Dapper.PagingSample 方法定义 以下是
推荐度:
导读基于Dapper实现分页效果 支持筛选、排序、结果集总数等:简介 之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护。 代码 首先先上代码: https://github.com/jinweijie/Dapper.PagingSample 方法定义 以下是


简介

之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护。

代码

首先先上代码: https://github.com/jinweijie/Dapper.PagingSample

方法定义

以下是我的一个分页的实现,虽然不是泛型(因为考虑到where条件以及sql语句的搭配),但是应该可以算是比较通用的了,方法定义如下:

public Tuple<IEnumerable<Log>, int> Find(LogSearchCriteria criteria
 , int pageIndex
 , int pageSize
 , string[] asc
 , string[] desc);

以上函数定义是一个查询Log的示例,返回结果中,Tuple的第一个值是结果集,第二个值是总行数(例如,总共有100条记录,每页10条,当前第一页,那么第一个值是10条记录,第二个值是100)

在示例项目中,我用两种方法实现了分页:

1. 第一种是基于2此查询,第一次得到总数,第二次查询得到结果集。

2. 第二种是基于1此查询,用了SqlServer 的Offest/Fetch,所以只支持Sql Server 2012+,所以大家根据自己用的Sql Server版本选择不同的实现,这里当然是第二种实现效率更高一点。

运行示例

1. 将Github的Repo下载或者Clone到本地以后,到Database目录下,解压缩Database.7z

2. Attach到Sql Server上。默认我使用Sql Server LocalDB,连接字符串是 Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DapperPagingSample;integrated security=True;   如果你用的不是LocalDB,请酌情修改App.Config的连接字符串。

3. Ctrl+F5运行程序,示例项目里,我用了一个简单的WinForm程序,但应该可以比较好的演示分页效果。

多表支持

增加了示例,支持多表查询,例如有两个Log表,Level表,Log的LevelId字段引用Level的Id字段,通过以下的查询,可以实现多表查询的分页,排序,过滤:

首先是通过两次查询的示例(基本支持所有版本Sql Server):

public Tuple<IEnumerable<Log>, int> Find(LogSearchCriteria criteria
 , int pageIndex
 , int pageSize
 , string[] asc
 , string[] desc)
 {
 using (IDbConnection connection = base.OpenConnection())
 {
 const string countQuery = @"SELECT COUNT(1)
 FROM [Log] l
 INNER JOIN [Level] lv ON l.LevelId = lv.Id
 /**where**/";

 const string selectQuery = @" SELECT *
 FROM ( SELECT ROW_NUMBER() OVER ( /**orderby**/ ) AS RowNum, l.*, lv.Name as [Level]
 FROM [Log] l
 INNER JOIN [Level] lv ON l.LevelId = lv.Id
 /**where**/
 ) AS RowConstrainedResult
 WHERE RowNum >= (@PageIndex * @PageSize + 1 )
 AND RowNum <= (@PageIndex + 1) * @PageSize
 ORDER BY RowNum";

 SqlBuilder builder = new SqlBuilder();

 var count = builder.AddTemplate(countQuery);
 var selector = builder.AddTemplate(selectQuery, new { PageIndex = pageIndex, PageSize = pageSize });

 if (!string.IsNullOrEmpty(criteria.Level))
 builder.Where("lv.Name= @Level", new { Level = criteria.Level });

 if (!string.IsNullOrEmpty(criteria.Message))
 {
 var msg = "%" + criteria.Message + "%";
 builder.Where("l.Message Like @Message", new { Message = msg });
 }

 foreach (var a in asc)
 {
 if(!string.IsNullOrWhiteSpace(a))
 builder.OrderBy(a);
 }

 foreach (var d in desc)
 {
 if (!string.IsNullOrWhiteSpace(d))
 builder.OrderBy(d + " desc");
 }

 var totalCount = connection.Query<int>(count.RawSql, count.Parameters).Single();
 var rows = connection.Query<Log>(selector.RawSql, selector.Parameters);

 return new Tuple<IEnumerable<Log>, int>(rows, totalCount);
 }
 }

第二个示例是通过Offset/Fetch查询(支持Sql Server 2012+)

public Tuple<IEnumerable<Log>, int> FindWithOffsetFetch(LogSearchCriteria criteria
 , int pageIndex
 , int pageSize
 , string[] asc
 , string[] desc)
 {
 using (IDbConnection connection = base.OpenConnection())
 {
 
 const string selectQuery = @" ;WITH _data AS (
 SELECT l.*, lv.Name AS [Level]
 FROM [Log] l
 INNER JOIN [Level] lv ON l.LevelId = lv.Id
 /**where**/
 ),
 _count AS (
 SELECT COUNT(1) AS TotalCount FROM _data
 )
 SELECT * FROM _data CROSS APPLY _count /**orderby**/ OFFSET @PageIndex * @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY";

 SqlBuilder builder = new SqlBuilder();
 
 var selector = builder.AddTemplate(selectQuery, new { PageIndex = pageIndex, PageSize = pageSize });

 if (!string.IsNullOrEmpty(criteria.Level))
 builder.Where("lv.Name = @Level", new { Level = criteria.Level });

 if (!string.IsNullOrEmpty(criteria.Message))
 {
 var msg = "%" + criteria.Message + "%";
 builder.Where("l.Message Like @Message", new { Message = msg });
 }
 
 foreach (var a in asc)
 {
 if (!string.IsNullOrWhiteSpace(a))
 builder.OrderBy(a);
 }

 foreach (var d in desc)
 {
 if (!string.IsNullOrWhiteSpace(d))
 builder.OrderBy(d + " desc");
 }
 
 var rows = connection.Query<Log>(selector.RawSql, selector.Parameters).ToList();

 if(rows.Count == 0)
 return new Tuple<IEnumerable<Log>, int>(rows, 0);
 

 return new Tuple<IEnumerable<Log>, int>(rows, rows[0].TotalCount);
 
 }
 }

文档

基于Dapper实现分页效果 支持筛选、排序、结果集总数等

基于Dapper实现分页效果 支持筛选、排序、结果集总数等:简介 之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护。 代码 首先先上代码: https://github.com/jinweijie/Dapper.PagingSample 方法定义 以下是
推荐度:
标签: 实现 排序 dapper
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top