2012-03-24 17 views
35

Ich versuche Dapper ORM und ich frage eine Posts-Tabelle.Dapper. Paging

Aber ich möchte ausgelagertem Ergebnisse erhalten ...

1 - Wie kann ich das tun? Gibt es dafür keinen Helfer?

2 - Kann Dapper-Abfrage ein IQueryable zurückgeben?

Danke, Miguel

+4

Da Sie gerade von Dapper erfahren haben ... Ich hoffe, Sie haben auch von [PetaPoco] (https://github.com/toptensoftware/PetaPoco) (mit integrierter Paging-Unterstützung) und [Massive] (https://github.com/robconery/massive) ... Nur FYI so wählen Sie die, die Ihnen am besten passt ... Sie sind alle extrem schnell und sehr ähnlich, aber immer noch anders. –

+0

siehe: http://samsaffron.com/archive/2011/09/05/Das+Siedelndes+Mess+der+Mess+Linq-2-SQL+erzeugt –

Antwort

28

1) Dapper hat kein Merkmal eingebaute in Paginierung. Aber es ist nicht zu schwer, es direkt in der Abfrage zu implementieren. Beispiel:

SELECT * 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY InsertDate) AS RowNum, * 
      FROM  Posts 
      WHERE  InsertDate >= '1900-01-01' 
     ) AS result 
WHERE RowNum >= 1 // *your pagination parameters 
    AND RowNum < 20 //* 
ORDER BY RowNum 

Erfordert SQL Server 2005+

2) Dapper gibt einen IEnumerable<T>.

+4

Aber wenn es ein IEnumerable zurückgibt, ist dies nicht geschlossen ? Ich meine, selbst wenn ich es zu IQueryable ändern würde, würde das Paging im Speicher und nicht in SQL Server erfolgen. Also ich denke, Ihre Vorgehensweise ist besser ... –

+3

Ja, die IEnumerable ist "geschlossen" und hat keine Verknüpfung zum Db-Kontext, wie Sie es vielleicht von einem IQueryable Kontext mit EF wissen. – Alex

+0

Dapper v1.13 führt eine .ToList() aus, wenn Sie den Standardpuffer nicht ändern. Auch der zugrunde liegende Code hat bereits die Abfrage ausgeführt und ergibt die IDataReader.Read(), so dass die Verwendung von Take und Skip nicht funktioniert. Also nein, Dapper kann kein IQueryable zurückgeben. – BillRob

55

Sie haben keine Datenbank oder Version angegeben. Wenn Sie das Glück haben, den brandneuen SQL Server 2012 verwenden und Zugriff auf MSDN haben zu können, können Sie die glänzenden neuen Schlüsselwörter OFFSET und FETCH verwenden. Die folgende Abfrage wird 20 Datensätze überspringen und die nächste 5.

SELECT * FROM [Posts] 
ORDER BY [InsertDate] 
OFFSET 20 ROWS 
FETCH NEXT 5 ROWS ONLY 

prüfen Rückkehr aus http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx#Offset für weitere Informationen.

Auch ist es einfach genug, den Weg zu kopieren Massive macht es und schreiben Sie Ihre eigene Erweiterungsmethode für IDbConnection. Hier ist Massives Code.

var query = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {2}) AS Row, {0} FROM {3} {4}) AS Paged ", columns, pageSize, orderBy, TableName, where); 
+0

Wusste nicht, dass SQL 2012 bereits verfügbar war. Ich dachte, es wäre auf RC ... Danke –

+7

Persönlich benutze ich SqlBuilder für dieses Zeug, stellt sich heraus, dass nicht-triviale Paging-Abfragen (insbesondere diejenigen, die Multi-Mapping involvieren) erfordern besondere Sorgfalt, um hohe Leistung zu erhalten siehe auch: http: // samsaffron.com/archive/2011/09/05/Schwung+aus dem+Messfeld+Linq-2-SQL+ erstellt –

+1

Diese Abfrage parametrisieren !! – pimbrouwers

-8

Wenn Sie nicht SQL Server 2012 haben, oder Sie haben andere DBMS, eine Möglichkeit, Paging zu tun ist, um die Verarbeitung zwischen der DBMS und dem Web-Server oder Client zu teilen. --- Dies ist nur für kleine Größe empfohlen. Sie können das Schlüsselwort 'TOP' in Sql Server oder LIMIT in MySql oder ROWNUM in Oracle verwenden, um die oberste Anzahl von Zeilen im Datensatz zu ermitteln. Die Anzahl der Zeilen, die Sie holen würde, ist gleich der Zahl, die Sie überspringen würde, plus die Anzahl, die Sie treffen würde:

top = skip + take; 

zum Beispiel, würden Sie wollen, 100 Zeilen überspringen und die nächste 50:

top = 100 + 50 

So SQL-Anweisung wie dieser (SQL Server Geschmack) aussehen würde

SELECT TOP 150 Name, Modified, content, Created 
FROM  Posts 
WHERE  Created >= '1900-01-01' 

auf dem Client: , wenn Sie eine .NET-Sprache wie C# und unter Verwendung von D verwenden apper, können Sie Linq verwenden, um eine Anzahl von Zeilen zu überspringen und eine Anzahl von Zeilen wie so nehmen:

var posts = connection.Query<Post>(sqlStatement, dynamicParameters); 
return posts?.ToList().Skip(skipValue).Take(takeValue); 
+1

Ich kann diese Lösung nicht empfehlen, denn wenn Sie viele Datensätze in Ihrer Datenbank haben, übertragen Sie alle Datensätze in Speicher und dann filtern Sie auf Ihrer Anwendungsseite. Sie sollten Daten auf DB-Seite filtern und paginieren. –

+2

Die obige Lösung besagt eindeutig, dass dies für eine kleine Set-Größe verwendet werden kann. Paging nach seiner eigenen Definition befasst sich mit einer kleinen Reihe von Aufzeichnungen. – ErnestoDeLucia

+0

Aber auch wenn Ihre ausgelagerten Daten eine kleine Menge von Daten sind, laden Sie immer noch den gesamten Satz zurück, der im Speicher sehr groß sein kann. –

0

ich ein Beispielprojekt erstellt die Dapper benutzerdefinierte Paging, Unterstützung Sortierung, Kriterien und Filter zur Demo:

https://github.com/jinweijie/Dapper.PagingSample

Grundsätzlich sieht das Verfahren wie folgt aus:

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

der erste Rückgabewert ist der Positionsliste.Der zweite Rückgabewert ist die Gesamtanzahl.

Ich hoffe, es hilft.

Danke.