Maison > développement back-end > Tutoriel C#.Net > Tutoriel sur la façon d'utiliser Dapper pour obtenir des effets de pagination

Tutoriel sur la façon d'utiliser Dapper pour obtenir des effets de pagination

巴扎黑
Libérer: 2018-05-24 16:47:05
original
4394 Les gens l'ont consulté

Cet article présente principalement en détail l'effet de pagination basé sur Dapper. Il prend en charge le filtrage, le tri, le nombre total d'ensembles de résultats, les requêtes multi-tables et les procédures non stockées. Il a une certaine valeur de référence. it.

Introduction

J'ai effectué des recherches sur le blog à l'avance sur la mise en œuvre de la pagination Dapper. Il y en a, mais elles sont soit basées sur des procédures stockées, soit sur la pagination de support, mais le tri n'est pas pris en charge ou les critères de recherche ne sont pas si faciles à gérer.

Définition de la méthode

Ce qui suit est mon implémentation de pagination Bien qu'elle ne soit pas générique (en raison des combinaisons de conditions Where et d'instructions SQL), elle doit être considérée comme l'est. plus général. La méthode est définie comme suit :

public Tuple<IEnumerable<Log>, int> Find(LogSearchCriteria criteria
      , int pageIndex
      , int pageSize
      , string[] asc
      , string[] desc);
Copier après la connexion

La définition de fonction ci-dessus est un exemple d'interrogation de Log Dans les résultats renvoyés, la première valeur de Tuple est l'ensemble de résultats et la deuxième valeur est. le nombre total de lignes (par exemple, il y a 100 enregistrements au total, 10 par page, et la première page actuelle, alors la première valeur est 10 enregistrements et la deuxième valeur est 100)

Dans l'échantillon projet, j'en utilise deux. La méthode implémente la pagination :

1. La première est basée sur 2 requêtes. La première fois est d'obtenir le nombre total, et la deuxième fois est d'obtenir l'ensemble de résultats.

2. La seconde est basée sur la requête 1, utilisant Offest/Fetch de SqlServer, elle ne prend donc en charge que Sql Server 2012+, vous pouvez donc choisir différentes implémentations en fonction de la version de Sql Server que vous utilisez ici. est bien sûr La deuxième implémentation est plus efficace.

Exécutez l'exemple

1. Après avoir téléchargé ou cloné le dépôt Github localement, accédez au répertoire Database.7z

2. Par défaut, j'utilise Sql Server LocalDB et la chaîne de connexion est Data Source=(localdb)MSSQLLocalDB;Initial Catalog=DapperPagingSample;integrated security=True; Si vous n'utilisez pas LocalDB, veuillez modifier la chaîne de connexion d'App.Config comme approprié. .

3. Ctrl+F5 pour exécuter le programme. Dans l'exemple de projet, j'ai utilisé un programme WinForm simple, mais il devrait être capable de mieux démontrer l'effet de pagination.

Prise en charge de plusieurs tables

Ajout d'exemples pour prendre en charge les requêtes multi-tables, par exemple, il existe deux tables de journal, une table de niveau , Log Le champ LevelId fait référence au champ Level Id. Grâce à la requête suivante, vous pouvez réaliser la pagination, le tri et le filtrage des requêtes multi-tables :

La première est un exemple de deux requêtes (prend en charge essentiellement toutes les requêtes). versions de 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);
      }
    }
Copier après la connexion

Le deuxième exemple est via une requête Offset/Fetch (prend en charge 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);
        
      }
    }
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal