>  기사  >  백엔드 개발  >  페이징 효과를 얻기 위해 Dapper를 사용하는 방법에 대한 튜토리얼

페이징 효과를 얻기 위해 Dapper를 사용하는 방법에 대한 튜토리얼

巴扎黑
巴扎黑원래의
2018-05-24 16:47:054268검색

이 글에서는 필터링, 정렬, 전체 결과 집합, 다중 테이블 쿼리 및 비저장 프로시저를 지원하는 Dapper 기반의 페이징 효과를 주로 자세히 소개합니다. 관심 있는 친구들은 참고할 수 있습니다. Introduction

Dapper paging 구현에 대해 미리 블로그를 검색해 본 것도 있는데 저장 프로시저를 기반으로 하거나 페이징을 지원하지만 정렬을 지원하지 않거나 검색 조건을 유지하기가 그리 쉽지 않습니다.

메서드 정의

다음은 내 페이징 구현입니다. 비록 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. 두 번째는 이 쿼리를 기반으로 하며 SqlServer의 Offest/Fetch를 사용하므로 Sql Server 2012+만 지원하므로 사용하는 SQL Server 버전에 따라 다른 구현을 선택할 수 있습니다. .좀 더 효율적입니다.

예제 실행

1. Github Repo를 로컬로 다운로드하거나 Clone한 후 Database 디렉터리로 이동하여 Database.7z

2의 압축을 풉니다. 기본적으로 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를 사용하는 방법에 대한 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.