2011-05-07 3 views
15

Je donne un essai à l'ORM Dapper. Je suis capable d'interroger des données à partir d'un tableau à l'aide du code ci-dessous:Dapper ORM pagination et le tri

Dim comments As List(Of Comment) 
Using conn = New SqlConnection(ConnectionString) 
    conn.Open() 
    comments = conn.Query(Of Comment)("SELECT * from comments where userid = @commentid", New With {.userid= 1}) 
End Using 

Return View(comments) 

Je suis intéressé à apprendre comment faire la pagination/tri en utilisant Dapper. EF a "sauter" et "prendre" pour aider à cela. Je comprends qu'un micro ORM n'a pas ce intégré mais voudrait savoir la meilleure manière d'accomplir ceci.

Répondre

19

Si vous voulez faire des sauts et des prises avec Dapper, you do it with T-SQL.

SELECT * 
FROM 
(
SELECT tbl.*, ROW_NUMBER() OVER (ORDER BY ID) rownum 
FROM comments as tbl 
) seq 
WHERE seq.rownum BETWEEN @x AND @y 
AND userid = @commentid 
ORDER BY seq.rownum 
+2

oui, gardez à l'esprit ce dépend db, oracle et MySQL ont limite et offset, denali a compensé etc. –

+1

Le ** où ** devrait être dans la requête interne, non? Et vous devriez probablement avoir une ** commande explicite par rownum ** sur la requête finale (cc @Sam) –

+1

@Marc oui vous auriez besoin d'une commande par alors à la fin .. l'où peut ou peut ne pas être nécessaire dans la requête interne , parfois vous pouvez ajouter un TOP @y à la requête interne pour obtenir un boost de perf –

0

Vous pouvez le faire maintenant.
Tout ce que vous aurez besoin de faire est d'écrire une méthode d'extension qui prend la requête et PageSize et PageNumber, alors vous devez ajouter le

OFFSET @PageSize * (@PageNumber - 1) ROWS FETCH NEXT @PageSize ROWS ONLY; 

ligne à la requête et exécuter.
Notez que la requête nécessite absolument une clause ORDER-BY (au moins dans T-SQL).
Cela fonctionnerait pour MS-SQL (2012+), PostgreSQL (8.4+) et Oracle (12c +).
Pour MySQL, vous devez ajouter LIMIT offset, page_size.

LIMIT @PageSize * (@PageNumber - 1), @PageSize 

Pour Oiseau de feu, vous auriez à ajouter des lignes x à y

ROWS (@PageSize * (@PageNumber - 1)) TO (@PageSize * @PageNumber -1) 

Pour un indice de base 1, il serait de startoffset_base1 à endoffset_base1

StartAt @PageSize * (pagenum - 1) + 1 EndAt @PageSize * (pagenum - 1) + @PageSize 

Exemple:

DECLARE @PageSize int 
DECLARE @PageNumber int 
SET @PageSize = 5 
SET @PageNumber = 2 

SELECT * FROM T_Users 
ORDER BY USR_ID 
-- Must contain "ORDER BY" 
OFFSET @PageSize * (@PageNumber - 1) ROWS FETCH NEXT @PageSize ROWS ONLY; 

Pour la syntaxe sur différents SGBDR différents, voir
http://www.jooq.org/doc/3.5/manual/sql-building/sql-statements/select-statement/limit-clause/

Vérification:

DECLARE @PageSize int 
SET @PageSize = 5 


;WITH CTE AS 
(
    SELECT 1 as pagenum 
    UNION ALL 

    SELECT pagenum+1 AS pagenum 
    FROM CTE 
    WHERE CTE.pagenum < 100 
) 
SELECT 
    pagenum 
    ,@PageSize * (pagenum - 1) AS StartOFFSETBase0 
    --,@PageSize * (pagenum - 1) + @PageSize - 1 AS EndOFFSETBase0 
    ,@PageSize * pagenum - 1 AS EndOFFSETBase0 -- Simplified 

    ,@PageSize * (pagenum - 1) + 1 AS StartOFFSETBase1 
    ,@PageSize * (pagenum - 1) + @PageSize AS EndOFFSETBase1 
FROM CTE