2011-05-07 36 views
15

Estoy dando la Dapper ORM una oportunidad. Soy capaz de consultar los datos de una tabla utilizando el código de abajo:Dapper ORM paginación y clasificación

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) 

estoy interesado en aprender a hacer paginación/clasificación utilizando Dapper. EF tiene "saltar" y "tomar" para ayudar con esto. Entiendo que un micro ORM no tiene esto incorporado pero me gustaría saber la mejor manera de lograrlo.

Respuesta

19

Si desea omitir y tomar con 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

sí, también tener en cuenta que es db dependiente, Oracle y MySQL no tienen límite y offset, Denali ha compensado y así. –

+1

El ** where ** debe estar dentro de la consulta interna, ¿no? Y probablemente debas tener un ** pedido por rownum ** en la consulta final (cc @Sam) –

+1

@Marc sí, necesitarías un pedido por al final ... el lugar puede o no ser necesario en la consulta interna , a veces puedes agregar TOP @y a la consulta interna para obtener un impulso de perf –

0

Lo puedes hacer ahora.
Todo lo que se necesita hacer es escribir un método de extensión que se lleva a la consulta y PageSize y PageNumber, entonces usted necesita para añadir una línea

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

a la consulta y ejecutar.
Tenga en cuenta que la consulta absolutamente requiere una cláusula ORDER-BY (al menos en T-SQL).
Esto funcionaría para MS-SQL (2012+), PostgreSQL (8.4+) y Oracle (12c +).
Para MySQL, tendría que anexar LIMIT offset, page_size.

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

para Firebird, habría que añadir filas x a y

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

Para un índice de base-1, sería de startoffset_base1 a endoffset_base1

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

Ejemplo:

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; 

Para la sintaxis de varios RDBMS diferentes, ver
http://www.jooq.org/doc/3.5/manual/sql-building/sql-statements/select-statement/limit-clause/

Verificación:

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