Effizientes Auslagern von großen Datenmengen (C#)
von Scott Mitchell
Die Standardauslagerungsoption eines Datenpräsentationssteuerelements ist bei der Arbeit mit großen Datenmengen ungeeignet, da das zugrunde liegende Datenquellensteuerelement alle Datensätze abruft, obwohl nur eine Teilmenge der Daten angezeigt wird. Unter diesen Umständen müssen wir uns dem benutzerdefinierten Paging zuwenden.
Einführung
Wie im vorherigen Tutorial erläutert, kann paging auf zwei Arten implementiert werden:
- Das Standard paging kann implementiert werden, indem einfach die Option Paging aktivieren im Smarttag des Datenwebsteuerelements aktiviert wird. Beim Anzeigen einer Datenseite ruft objectDataSource jedoch alle Datensätze ab, obwohl nur eine Teilmenge von ihnen auf der Seite angezeigt wird.
- Benutzerdefiniertes Paging verbessert die Leistung des Standardpapageings, indem nur die Datensätze aus der Datenbank abgerufen werden, die für die jeweilige Seite der vom Benutzer angeforderten Daten angezeigt werden müssen. Benutzerdefiniertes Paging erfordert jedoch etwas mehr Aufwand für die Implementierung als das Standardpa paging.
Aufgrund der einfachen Implementierung aktivieren Sie einfach ein Kontrollkästchen und Fertig! Die Standardpa paging ist eine attraktive Option. Sein naiver Ansatz beim Abrufen aller Datensätze macht es jedoch zu einer unglaubwürdigen Wahl, wenn ausreichend große Datenmengen oder für Websites mit vielen gleichzeitigen Benutzern durchlaufen werden. In solchen Fällen müssen wir auf benutzerdefiniertes Paging umstellen, um ein reaktionsfähiges System bereitzustellen.
Die Herausforderung des benutzerdefinierten Pagings besteht darin, eine Abfrage schreiben zu können, die den genauen Satz von Datensätzen zurückgibt, die für eine bestimmte Datenseite erforderlich sind. Glücklicherweise bietet Microsoft SQL Server 2005 eine neue Schlüsselwort (keyword) für Bewertungsergebnisse, die es uns ermöglicht, eine Abfrage zu schreiben, die die richtige Teilmenge von Datensätzen effizient abrufen kann. In diesem Tutorial erfahren Sie, wie Sie dieses neue SQL Server 2005 Schlüsselwort (keyword) verwenden, um benutzerdefiniertes Paging in einem GridView-Steuerelement zu implementieren. Während die Benutzeroberfläche für benutzerdefiniertes Paging mit der benutzerdefinierten Paging-Benutzeroberfläche identisch ist, kann das Schrittweisen von einer Seite zur nächsten mithilfe des benutzerdefinierten Pagings mehrere Größenordnungen schneller sein als das Standardpapageing.
Hinweis
Der genaue Leistungsgewinn, der durch benutzerdefiniertes Paging erzielt wird, hängt von der Gesamtzahl der Datensätze ab, die durchlaufen werden, und von der Last, die auf dem Datenbankserver platziert wird. Am Ende dieses Tutorials sehen wir uns einige grobe Metriken an, die die Vorteile der Leistung durch benutzerdefiniertes Paging aufzeigen.
Schritt 1: Grundlegendes zum benutzerdefinierten Pagingprozess
Beim Paging von Daten hängen die genauen Datensätze, die auf einer Seite angezeigt werden, von der Seite der angeforderten Daten und der Anzahl der pro Seite angezeigten Datensätze ab. Stellen Sie sich beispielsweise vor, wir wollten die 81 Produkte durchblättern und 10 Produkte pro Seite anzeigen. Beim Anzeigen der ersten Seite möchten wir die Produkte 1 bis 10; beim Anzeigen der zweiten Seite wären wir an den Produkten 11 bis 20 interessiert, usw.
Es gibt drei Variablen, die bestimmen, welche Datensätze abgerufen werden müssen und wie die Pagingschnittstelle gerendert werden soll:
- Start Row Index the index of the first row in the page of data to display; Dieser Index kann berechnet werden, indem der Seitenindex mit den Datensätzen multipliziert wird, die pro Seite angezeigt werden sollen, und einen hinzufügen. Wenn Sie beispielsweise datensätze 10 gleichzeitig durchlaufen, ist der Startzeilenindex für die erste Seite (deren Seitenindex 0 ist) 0 * 10 + 1 oder 1; für die zweite Seite (deren Seitenindex 1 ist) ist der Startzeilenindex 1 * 10 + 1 oder 11.
- Maximale Anzahl von Zeilen die maximale Anzahl von Datensätzen, die pro Seite angezeigt werden sollen. Diese Variable wird als maximale Zeilen bezeichnet, da für die letzte Seite möglicherweise weniger Datensätze zurückgegeben werden als die Seitengröße. Wenn Sie beispielsweise die 81 Produkte mit 10 Datensätzen pro Seite durchblättern, verfügt die neunte und letzte Seite nur über einen Datensatz. Auf keiner Seite werden jedoch mehr Datensätze als der Wert für maximale Zeilen angezeigt.
- Datensatzanzahl insgesamt die Gesamtanzahl der Datensätze, die ausgelagert werden. Diese Variable ist zwar nicht erforderlich, um zu bestimmen, welche Datensätze für eine bestimmte Seite abgerufen werden sollen, aber sie diktiert die Pagingschnittstelle. Wenn beispielsweise 81 Produkte ausgelagert werden, kann die Pagingschnittstelle neun Seitenzahlen auf der Paging-Benutzeroberfläche anzeigen.
Beim Standardpapageing wird der Startzeilenindex als Produkt des Seitenindexes und der Seitengröße plus 1 berechnet, während die Maximale Zeilen einfach die Seitengröße ist. Da das Standardpapageing beim Rendern einer beliebigen Datenseite alle Datensätze aus der Datenbank abruft, ist der Index für jede Zeile bekannt, sodass das Verschieben zur Zeile "Zeilenindex starten" eine triviale Aufgabe ist. Darüber hinaus ist die Gesamtzahl der Datensätze leicht verfügbar, da es sich einfach um die Anzahl der Datensätze in der DataTable handelt (oder um ein beliebiges Objekt, das zum Speichern der Datenbankergebnisse verwendet wird).
Angesichts der Variablen Zeilenindex starten und maximale Zeilen darf eine benutzerdefinierte Pagingimplementierung nur die genaue Teilmenge der Datensätze zurückgeben, die mit dem Startzeilenindex beginnen und danach bis zur maximalen Zeilenanzahl von Datensätzen beginnen. Benutzerdefinierte Paging bietet zwei Herausforderungen:
- Wir müssen in der Lage sein, jeder Zeile in den durchblätternden Daten einen Zeilenindex effizient zuzuordnen, damit wir mit der Rückgabe von Datensätzen am angegebenen Startzeilenindex beginnen können.
- Wir müssen die Gesamtanzahl der Datensätze angeben, die ausgelagert werden.
In den nächsten beiden Schritten untersuchen wir das SQL-Skript, das erforderlich ist, um auf diese beiden Herausforderungen zu reagieren. Zusätzlich zum SQL-Skript müssen wir auch Methoden in der DAL und BLL implementieren.
Schritt 2: Zurückgeben der Gesamtanzahl der Datensätze, die durchgesendet werden
Bevor wir untersuchen, wie die genaue Teilmenge der Datensätze für die angezeigte Seite abgerufen werden kann, sehen wir uns zunächst an, wie die Gesamtanzahl der Datensätze zurückgegeben wird, die ausgelagert werden. Diese Informationen sind erforderlich, um die Paging-Benutzeroberfläche ordnungsgemäß zu konfigurieren. Die Gesamtzahl der von einer bestimmten SQL-Abfrage zurückgegebenen Datensätze kann mithilfe der COUNT
Aggregatfunktion abgerufen werden. Um beispielsweise die Gesamtzahl der Datensätze in der Products
Tabelle zu bestimmen, können wir die folgende Abfrage verwenden:
SELECT COUNT(*)
FROM Products
Fügen Sie unserer DAL eine Methode hinzu, die diese Informationen zurückgibt. Insbesondere erstellen wir eine DAL-Methode namens TotalNumberOfProducts()
, die die SELECT
oben gezeigte Anweisung ausführt.
Öffnen Sie zunächst die Northwind.xsd
Typisierte DataSet-Datei im App_Code/DAL
Ordner. Klicken Sie als Nächstes mit der rechten Maustaste auf die ProductsTableAdapter
in der Designer, und wählen Sie Abfrage hinzufügen aus. Wie wir in früheren Tutorials gesehen haben, können wir auf diese Weise der DAL eine neue Methode hinzufügen, die beim Aufrufen eine bestimmte SQL-Anweisung oder gespeicherte Prozedur ausführt. Wie bei unseren TableAdapter-Methoden in den vorherigen Tutorials entscheiden Sie sich für diese Methode für die Verwendung einer Ad-hoc-SQL-Anweisung.
Abbildung 1: Verwenden einer Ad-Hoc-SQL-Anweisung
Auf dem nächsten Bildschirm können wir angeben, welcher Abfragetyp erstellt werden soll. Da diese Abfrage einen einzelnen skalaren Wert zurückgibt, wählen Sie die Gesamtzahl der Datensätze in der Products
Tabelle aus, die SELECT
eine Singe-Wert-Option zurückgibt.
Abbildung 2: Konfigurieren der Abfrage für die Verwendung einer SELECT-Anweisung, die einen einzelnen Wert zurückgibt
Nachdem Sie den Typ der zu verwendenden Abfrage angegeben haben, müssen Sie als Nächstes die Abfrage angeben.
Abbildung 3: Verwenden der SELECT COUNT(*) FROM Products-Abfrage
Geben Sie schließlich den Namen für die -Methode an. Wie bereits erwähnt, verwenden TotalNumberOfProducts
wir .
Abbildung 4: Name der DAL-Methode TotalNumberOfProducts
Nachdem Sie auf Fertig stellen geklickt haben, fügt der Assistent die TotalNumberOfProducts
-Methode der DAL hinzu. Die skalaren Methoden, die in der DAL zurückgeben, geben NULLable-Typen zurück, falls das Ergebnis der SQL-Abfrage lautet NULL
. Unsere COUNT
Abfrage gibt jedoch immer einen Nicht-Wert zurück. Unabhängig davon gibt die DAL-MethodeNULL
eine nullable ganze Zahl zurück.
Zusätzlich zur DAL-Methode benötigen wir auch eine Methode in der BLL. Öffnen Sie die ProductsBLL
Klassendatei, und fügen Sie eine TotalNumberOfProducts
Methode hinzu, die einfach die DAL-Methode TotalNumberOfProducts
aufruft:
public int TotalNumberOfProducts()
{
return Adapter.TotalNumberOfProducts().GetValueOrDefault();
}
Die DAL s-Methode TotalNumberOfProducts
gibt eine ganze Nullable-Zahl zurück. Wir haben jedoch die Methode s TotalNumberOfProducts
der ProductsBLL
Klasse erstellt, sodass sie eine ganzzahlige Standardversion zurückgibt. Daher muss die s-Methode der ProductsBLL
Klasse TotalNumberOfProducts
den Wertteil der ganzen Nullable-Zahl zurückgeben, die von der DAL s-Methode TotalNumberOfProducts
zurückgegeben wird. Der Aufruf von GetValueOrDefault()
gibt den Wert der ganzen Nullable-Zahl zurück, sofern vorhanden. Wenn die ganze Nullable-Zahl ist, gibt null
sie jedoch den ganzzahligen Standardwert 0 zurück.
Schritt 3: Zurückgeben der präzisen Teilmenge der Datensätze
Unsere nächste Aufgabe besteht darin, Methoden in der DAL und BLL zu erstellen, die die Variablen Zeilenindex starten und maximale Zeilen akzeptieren, die zuvor erläutert wurden, und die entsprechenden Datensätze zurückgeben. Bevor wir dies tun, sehen wir uns zunächst das erforderliche SQL-Skript an. Die Herausforderung besteht darin, dass wir in der Lage sein müssen, jeder Zeile in den gesamten Durchblätternden Ergebnissen einen Index effizient zuzuweisen, damit wir nur diese Datensätze zurückgeben können, die mit dem Startzeilenindex beginnen (und bis zur maximalen Datensatzanzahl von Datensätzen).
Dies ist keine Herausforderung, wenn in der Datenbanktabelle bereits eine Spalte vorhanden ist, die als Zeilenindex dient. Auf den ersten Blick könnte man denken, dass das Feld der Products
ProductID
Tabelle ausreichen würde, da das erste Produkt 1 hat ProductID
, der zweite eine 2 usw. Das Löschen eines Produkts hinterlässt jedoch eine Lücke in der Sequenz, was diesen Ansatz zunichte macht.
Es gibt zwei allgemeine Techniken, die verwendet werden, um einen Zeilenindex effizient mit den Daten zu verknüpfen, die ausgelagert werden sollen, sodass die genaue Teilmenge der Datensätze abgerufen werden kann:
Mit SQL Server Schlüsselwort 2005 s
ROW_NUMBER()
neu auf SQL Server 2005 ordnet dieROW_NUMBER()
Schlüsselwort (keyword) jedem zurückgegebenen Datensatz basierend auf einer bestimmten Reihenfolge eine Rangfolge zu. Diese Rangfolge kann als Zeilenindex für jede Zeile verwendet werden.Verwenden einer Tabellenvariablen und
SET ROWCOUNT
SQL Server s-AnweisungSET ROWCOUNT
kann verwendet werden, um anzugeben, wie viele Datensätze insgesamt eine Abfrage vor dem Beenden verarbeiten soll. Tabellenvariablen sind lokale T-SQL-Variablen, die tabellarische Daten enthalten können, ähnlich wie temporäre Tabellen. Dieser Ansatz funktioniert sowohl mit Microsoft SQL Server 2005 als auch mit SQL Server 2000 gleichermaßen (während derROW_NUMBER()
Ansatz nur mit SQL Server 2005 funktioniert).Die Idee besteht darin, eine Tabellenvariable zu erstellen, die eine
IDENTITY
Spalte und Spalten für die Primärschlüssel der Tabelle enthält, deren Daten ausgelagert werden. Als Nächstes wird der Inhalt der Tabelle, deren Daten ausgelagert werden, in der Tabellenvariablen gespeichert, wodurch jedem Datensatz in der Tabelle ein sequenzieller Zeilenindex (über dieIDENTITY
Spalte) zugeordnet wird. Nachdem die Tabellenvariable aufgefüllt wurde, kann eineSELECT
Anweisung für die Tabellenvariable ausgeführt werden, die mit der zugrunde liegenden Tabelle verknüpft ist, um die jeweiligen Datensätze herauszuziehen. DieSET ROWCOUNT
-Anweisung wird verwendet, um die Anzahl der Datensätze, die in der Tabellenvariablen gespeichert werden müssen, intelligent zu begrenzen.Die Effizienz dieses Ansatzes basiert auf der angeforderten Seitenzahl, da dem
SET ROWCOUNT
Wert der Wert des Startzeilenindex und der Maximalen Zeilen zugewiesen wird. Beim Paging durch Seiten mit niedriger Anzahl, z. B. die ersten Datenseiten, ist dieser Ansatz sehr effizient. Es weist jedoch beim Abrufen einer Seite am Ende eine standardmäßige Paging-ähnliche Leistung auf.
In diesem Tutorial wird benutzerdefiniertes Paging mithilfe der ROW_NUMBER()
Schlüsselwort (keyword) implementiert. Weitere Informationen zur Verwendung der Tabellenvariablen und SET ROWCOUNT
-technik finden Sie unter Effizientes Paging durch große Datenmengen.
Die ROW_NUMBER()
Schlüsselwort (keyword) jedem Datensatz, der über eine bestimmte Reihenfolge zurückgegeben wird, mithilfe der folgenden Syntax eine Rangfolge zugeordnet:
SELECT columnList,
ROW_NUMBER() OVER(orderByClause)
FROM TableName
ROW_NUMBER()
gibt einen numerischen Wert zurück, der den Rang für jeden Datensatz in Bezug auf die angegebene Reihenfolge angibt. Um z. B. den Rang für jedes Produkt anzuzeigen, das vom teuersten zum niedrigsten bestellt wurde, können wir die folgende Abfrage verwenden:
SELECT ProductName, UnitPrice,
ROW_NUMBER() OVER(ORDER BY UnitPrice DESC) AS PriceRank
FROM Products
Abbildung 5 zeigt die Ergebnisse dieser Abfrage, wenn sie durch das Abfragefenster in Visual Studio ausgeführt werden. Beachten Sie, dass die Produkte nach Preis bestellt werden, zusammen mit einem Preisrang für jede Zeile.
Abbildung 5: Der Preisrang ist für jeden zurückgegebenen Datensatz enthalten.
Hinweis
ROW_NUMBER()
ist nur eine der vielen neuen Rangfolgefunktionen, die in SQL Server 2005 verfügbar sind. Eine ausführlichere Erläuterung von ROW_NUMBER()
finden Sie zusammen mit den anderen Rangfolgefunktionen unter Zurückgeben von bewerteten Ergebnissen mit Microsoft SQL Server 2005.
Beim Rangieren der Ergebnisse nach der angegebenen ORDER BY
Spalte in der OVER
-Klausel (UnitPrice
im obigen Beispiel) müssen SQL Server die Ergebnisse sortieren. Dies ist ein schneller Vorgang, wenn ein gruppierter Index über den Spalten vorhanden ist, nach denen die Ergebnisse sortiert werden, oder wenn ein abdeckender Index vorhanden ist, der andernfalls teurer sein kann. Um die Leistung für ausreichend große Abfragen zu verbessern, sollten Sie einen nicht gruppierten Index für die Spalte hinzufügen, nach der die Ergebnisse sortiert werden. Ausführlichere Informationen zu den Leistungsüberlegungen finden Sie unter Rangfolgefunktionen und Leistung in SQL Server 2005.
Die von ROW_NUMBER()
zurückgegebenen Rangfolgeinformationen können nicht direkt in der WHERE
-Klausel verwendet werden. Allerdings kann eine abgeleitete Tabelle verwendet werden, um das ROW_NUMBER()
Ergebnis zurückzugeben, das dann in der WHERE
-Klausel angezeigt werden kann. Die folgende Abfrage verwendet z. B. eine abgeleitete Tabelle, um die Spalten ProductName und UnitPrice zusammen mit dem ROW_NUMBER()
Ergebnis zurückzugeben, und verwendet dann eine WHERE
-Klausel, um nur die Produkte zurückzugeben, deren Preisrang zwischen 11 und 20 liegt:
SELECT PriceRank, ProductName, UnitPrice
FROM
(SELECT ProductName, UnitPrice,
ROW_NUMBER() OVER(ORDER BY UnitPrice DESC) AS PriceRank
FROM Products
) AS ProductsWithRowNumber
WHERE PriceRank BETWEEN 11 AND 20
Um dieses Konzept ein wenig weiter zu erweitern, können wir diesen Ansatz verwenden, um eine bestimmte Seite von Daten unter Berücksichtigung der gewünschten Werte für Zeilenindex und maximale Zeilen abzurufen:
SELECT PriceRank, ProductName, UnitPrice
FROM
(SELECT ProductName, UnitPrice,
ROW_NUMBER() OVER(ORDER BY UnitPrice DESC) AS PriceRank
FROM Products
) AS ProductsWithRowNumber
WHERE PriceRank > <i>StartRowIndex</i> AND
PriceRank <= (<i>StartRowIndex</i> + <i>MaximumRows</i>)
Hinweis
Wie wir später in diesem Tutorial sehen werden, wird die StartRowIndex
von ObjectDataSource bereitgestellte ab 0 (null) indiziert, während der ROW_NUMBER()
von SQL Server 2005 zurückgegebene Wert ab 1 indiziert wird. Daher gibt die WHERE
-Klausel die Datensätze zurück, bei denen PriceRank
streng größer als StartRowIndex
und kleiner oder gleich StartRowIndex
+ MaximumRows
ist.
Nachdem wir nun erläutert haben, wie ROW_NUMBER()
eine bestimmte Seite von Daten abgerufen werden kann, wenn die Werte Zeilenindex starten und Maximale Zeilen angegeben sind, müssen wir diese Logik nun als Methoden in der DAL und BLL implementieren.
Beim Erstellen dieser Abfrage müssen wir die Reihenfolge bestimmen, nach der die Ergebnisse bewertet werden. sortieren wir die Produkte nach ihrem Namen in alphabetischer Reihenfolge. Dies bedeutet, dass mit der benutzerdefinierten Pagingimplementierung in diesem Tutorial kein benutzerdefinierter ausgelagerter Bericht erstellt werden kann, als auch sortiert werden kann. Im nächsten Tutorial wird jedoch erläutert, wie solche Funktionen bereitgestellt werden können.
Im vorherigen Abschnitt haben wir die DAL-Methode als Ad-hoc-SQL-Anweisung erstellt. Leider gefällt der T-SQL-Parser in Visual Studio, der vom TableAdapter-Assistenten verwendet wird, nicht mit der OVER
Syntax, die von der ROW_NUMBER()
Funktion verwendet wird. Daher müssen wir diese DAL-Methode als gespeicherte Prozedur erstellen. Wählen Sie im Menü Ansicht die Explorer Server aus (oder drücken Sie STRG+ALT+S), und erweitern Sie den NORTHWND.MDF
Knoten. Klicken Sie zum Hinzufügen einer neuen gespeicherten Prozedur mit der rechten Maustaste auf den Knoten Gespeicherte Prozeduren, und wählen Sie Neue gespeicherte Prozedur hinzufügen aus (siehe Abbildung 6).
Abbildung 6: Hinzufügen einer neuen gespeicherten Prozedur für das Paging durch die Produkte
Diese gespeicherte Prozedur sollte zwei ganzzahlige Eingabeparameter akzeptieren – und die funktion nach dem ProductName
Feld geordnet verwenden, wobei nur die Zeilen zurückgegeben werden, die größer als die angegebene @startRowIndex
und kleiner als oder gleich + @maximumRow
@startRowIndex
s sind.ROW_NUMBER()
@maximumRows
@startRowIndex
Geben Sie das folgende Skript in die neue gespeicherte Prozedur ein, und klicken Sie dann auf das Symbol Speichern, um die gespeicherte Prozedur der Datenbank hinzuzufügen.
CREATE PROCEDURE dbo.GetProductsPaged
(
@startRowIndex int,
@maximumRows int
)
AS
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit,
UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
CategoryName, SupplierName
FROM
(
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit,
UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
(SELECT CategoryName
FROM Categories
WHERE Categories.CategoryID = Products.CategoryID) AS CategoryName,
(SELECT CompanyName
FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID) AS SupplierName,
ROW_NUMBER() OVER (ORDER BY ProductName) AS RowRank
FROM Products
) AS ProductsWithRowNumbers
WHERE RowRank > @startRowIndex AND RowRank <= (@startRowIndex + @maximumRows)
Nehmen Sie sich nach dem Erstellen der gespeicherten Prozedur einen Moment Zeit, um sie auszuprobieren. Klicken Sie im serverbasierten Explorer mit der GetProductsPaged
rechten Maustaste auf den Namen der gespeicherten Prozedur, und wählen Sie die Option Ausführen aus. Visual Studio fordert Sie dann zur Eingabe der Eingabeparameter @startRowIndex
und @maximumRow
der Eingabe auf (siehe Abbildung 7). Probieren Sie verschiedene Werte aus, und untersuchen Sie die Ergebnisse.
@startRowIndex and @maximumRows Parameters" />
Abbildung 7: Eingeben eines Werts für die @startRowIndex Parameter und @maximumRows
Nachdem Sie diese Eingabeparameterwerte ausgewählt haben, werden im Fenster Ausgabe die Ergebnisse angezeigt. Abbildung 8 zeigt die Ergebnisse bei der Übergabe von 10 für die @startRowIndex
Parameter und @maximumRows
.
Abbildung 8: Die Datensätze, die auf der zweiten Seite der Daten angezeigt werden, werden zurückgegeben (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nachdem diese gespeicherte Prozedur erstellt wurde, können wir die ProductsTableAdapter
-Methode erstellen. Öffnen Sie das Northwind.xsd
Typisierte DataSet, klicken Sie mit der rechten Maustaste auf , ProductsTableAdapter
und wählen Sie die Option Abfrage hinzufügen aus. Anstatt die Abfrage mithilfe einer Ad-hoc-SQL-Anweisung zu erstellen, erstellen Sie sie mithilfe einer vorhandenen gespeicherten Prozedur.
Abbildung 9: Erstellen der DAL-Methode mithilfe einer vorhandenen gespeicherten Prozedur
Als Nächstes werden wir aufgefordert, die aufzurufende gespeicherte Prozedur auszuwählen. Wählen Sie die GetProductsPaged
gespeicherte Prozedur aus der Dropdownliste aus.
Abbildung 10: Auswählen der gespeicherten GetProductsPaged-Prozedur aus der liste Drop-Down
Auf dem nächsten Bildschirm werden Sie dann gefragt, welche Art von Daten von der gespeicherten Prozedur zurückgegeben wird: tabellarische Daten, ein einzelner Wert oder kein Wert. Da die GetProductsPaged
gespeicherte Prozedur mehrere Datensätze zurückgeben kann, geben Sie an, dass tabellarische Daten zurückgegeben werden.
Abbildung 11: Angeben, dass die gespeicherte Prozedur tabellarische Daten zurückgibt
Geben Sie schließlich die Namen der Methoden an, die Sie erstellen möchten. Wie in unseren vorherigen Tutorials können Sie methoden erstellen, indem Sie sowohl eine DataTable ausfüllen als auch Eine DataTable zurückgeben verwenden. Nennen Sie die erste Methode FillPaged
und die zweite GetProductsPaged
.
Abbildung 12: Benennen der Methoden FillPaged und GetProductsPaged
Zusätzlich zur Erstellung einer DAL-Methode, um eine bestimmte Produktseite zurückzugeben, müssen wir diese Funktionalität auch in der BLL bereitstellen. Wie bei der DAL-Methode muss die GetProductsPaged-Methode von BLL zwei ganzzahlige Eingaben zum Angeben des Zeilenindexes und der maximalen Zeilen akzeptieren und nur die Datensätze zurückgeben, die innerhalb des angegebenen Bereichs liegen. Erstellen Sie eine solche BLL-Methode in der ProductsBLL-Klasse, die lediglich die DAL s GetProductsPaged-Methode aufruft, wie so:
[System.ComponentModel.DataObjectMethodAttribute(
System.ComponentModel.DataObjectMethodType.Select, false)]
public Northwind.ProductsDataTable GetProductsPaged(int startRowIndex, int maximumRows)
{
return Adapter.GetProductsPaged(startRowIndex, maximumRows);
}
Sie können einen beliebigen Namen für die Eingabeparameter der BLL-Methode verwenden, aber wie wir in Kürze sehen werden, wird die Verwendung startRowIndex
von und maximumRows
uns vor einem zusätzlichen Arbeitsaufwand beim Konfigurieren einer ObjectDataSource für die Verwendung dieser Methode gespeichert.
Schritt 4: Konfigurieren von ObjectDataSource für die Verwendung von benutzerdefiniertem Paging
Wenn die BLL- und DAL-Methoden für den Zugriff auf eine bestimmte Teilmenge von Datensätzen abgeschlossen sind, sind wir bereit, ein GridView-Steuerelement zu erstellen, das die zugrunde liegenden Datensätze mithilfe von benutzerdefiniertem Paging durchläuft. Öffnen Sie zunächst die EfficientPaging.aspx
Seite im PagingAndSorting
Ordner, fügen Sie der Seite ein GridView hinzu, und konfigurieren Sie sie für die Verwendung eines neuen ObjectDataSource-Steuerelements. In unseren vorherigen Tutorials wurde die ObjectDataSource häufig für die Verwendung der ProductsBLL
Klasse s-Methode GetProducts
konfiguriert. Dieses Mal möchten wir jedoch stattdessen die GetProductsPaged
-Methode verwenden, da die GetProducts
-Methode alle Produkte in der Datenbank zurückgibt, während GetProductsPaged
nur eine bestimmte Teilmenge von Datensätzen zurückgibt.
Abbildung 13: Konfigurieren der ObjectDataSource für die Verwendung der GetProductsPaged-Methode der ProductsBLL-Klasse
Da wir ein schreibgeschütztes GridView-Objekt erstellen, nehmen Sie sich einen Moment Zeit, um die Dropdownliste der Methode in den Registerkarten INSERT, UPDATE und DELETE auf (Keine) festzulegen.
Als Nächstes werden wir vom ObjectDataSource-Assistenten aufgefordert, die Quellen der Werte der GetProductsPaged
Methoden s startRowIndex
und maximumRows
Eingabeparameter einzugeben. Diese Eingabeparameter werden von GridView automatisch festgelegt. Lassen Sie die Quelle also einfach auf Keine festgelegt, und klicken Sie auf Fertig stellen.
Abbildung 14: Belassen der Eingabeparameterquellen als "None"
Nach Abschluss des ObjectDataSource-Assistenten enthält gridView ein BoundField- oder CheckBoxField-Element für jedes Produktdatenfeld. Sie können das Erscheinungsbild von GridView nach Ihren Anforderungen anpassen. Ich habe mich dafür entschieden, nur die ProductName
BoundFields, CategoryName
SupplierName
, , QuantityPerUnit
und UnitPrice
anzuzeigen. Konfigurieren Sie gridView außerdem so, dass paging unterstützt wird, indem Sie das Kontrollkästchen Paging aktivieren in seinem Smarttag aktivieren. Nach diesen Änderungen sollte das deklarative Markup GridView und ObjectDataSource in etwa wie folgt aussehen:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit" HeaderText="Qty/Unit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False" SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProductsPaged"
TypeName="ProductsBLL">
<SelectParameters>
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Wenn Sie die Seite jedoch über einen Browser aufrufen, ist die GridView nicht zu finden.
Abbildung 15: GridView wird nicht angezeigt
GridView fehlt, da objectDataSource derzeit 0 als Werte für die GetProductsPaged
startRowIndex
Eingabeparameter und maximumRows
verwendet. Daher gibt die resultierende SQL-Abfrage keine Datensätze zurück, und daher wird gridView nicht angezeigt.
Um dies zu beheben, müssen wir objectDataSource so konfigurieren, dass benutzerdefiniertes Paging verwendet wird. Dies kann in den folgenden Schritten erreicht werden:
- Legen Sie die ObjectDataSource-Eigenschaft
EnablePaging
auftrue
fest, die an die ObjectDataSource übergeben wird, die an dieSelectMethod
beiden zusätzlichen Parameter übergeben werden muss: einer, um den Zeilenindex starten (StartRowIndexParameterName
) anzugeben, und einer, um die maximale Zeilenanzahl (MaximumRowsParameterName
) anzugeben. - Legen Sie objectDataSource s
StartRowIndexParameterName
undMaximumRowsParameterName
Properties fest Entsprechend geben dieStartRowIndexParameterName
Eigenschaften undMaximumRowsParameterName
die Namen der Eingabeparameter an, dieSelectMethod
für benutzerdefinierte Pagingzwecke übergeben werden. Standardmäßig sindstartIndexRow
diese Parameternamen undmaximumRows
, weshalb ich beim Erstellen derGetProductsPaged
Methode in der BLL diese Werte für die Eingabeparameter verwendet habe. Wenn Sie verschiedene Parameternamen für die BLL-MethodeGetProductsPaged
verwenden möchten, zstartIndex
. B. undmaxRows
, müssen Sie die ObjectDataSource-EigenschaftenStartRowIndexParameterName
undMaximumRowsParameterName
die Eigenschaften entsprechend festlegen (z. B. startIndex fürStartRowIndexParameterName
und maxRows fürMaximumRowsParameterName
). - Legen Sie die ObjectDataSource-Eigenschaft
SelectCountMethod
auf den Namen der Methode fest, die die Gesamtanzahl der Datensätze zurückgibt, die ausgelagert werden (TotalNumberOfProducts
), erinnern Sie daran, dass die Methode derProductsBLL
Klasse sTotalNumberOfProducts
die Gesamtanzahl der Datensätze zurückgibt, die ausgelagert werden, indem eine DAL-Methode verwendet wird, die eineSELECT COUNT(*) FROM Products
Abfrage ausführt. Diese Informationen werden von ObjectDataSource benötigt, um die Pagingschnittstelle ordnungsgemäß zu rendern. - Entfernen Sie die
startRowIndex
Elemente undmaximumRows
<asp:Parameter>
aus dem deklarativen Markup von ObjectDataSource beim Konfigurieren der ObjectDataSource über den Assistenten. Visual Studio hat automatisch zwei<asp:Parameter>
Elemente für die Eingabeparameter derGetProductsPaged
Methode hinzugefügt. Wenn Sie auftrue
festlegenEnablePaging
, werden diese Parameter automatisch übergeben. Wenn sie auch in der deklarativen Syntax angezeigt werden, versucht objectDataSource, vier Parameter an dieGetProductsPaged
-Methode und zwei Parameter an dieTotalNumberOfProducts
-Methode zu übergeben. Wenn Sie vergessen, diese<asp:Parameter>
Elemente zu entfernen, erhalten Sie beim Aufrufen der Seite über einen Browser eine Fehlermeldung wie: ObjectDataSource 'ObjectDataSource1' konnte keine nicht generische Methode 'TotalNumberOfProducts' finden, die Parameter hat: startRowIndex, maximumRows.
Nachdem Sie diese Änderungen vorgenommen haben, sollte die deklarative Syntax von ObjectDataSource wie folgt aussehen:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProductsPaged" EnablePaging="True"
SelectCountMethod="TotalNumberOfProducts">
</asp:ObjectDataSource>
Beachten Sie, dass die EnablePaging
Eigenschaften und SelectCountMethod
festgelegt und die <asp:Parameter>
Elemente entfernt wurden. Abbildung 16 zeigt einen Screenshot der Eigenschaftenfenster, nachdem diese Änderungen vorgenommen wurden.
Abbildung 16: Konfigurieren des ObjectDataSource-Steuerelements, um benutzerdefiniertes Paging zu verwenden
Nachdem Sie diese Änderungen vorgenommen haben, besuchen Sie diese Seite über einen Browser. Sie sollten 10 Produkte aufgelistet sehen, die alphabetisch sortiert sind. Nehmen Sie sich einen Moment Zeit, um die Daten einzeln zu durchlaufen. Es gibt zwar keinen visuellen Unterschied aus sicht des Endbenutzers zwischen Standardpapageing und benutzerdefiniertem Paging, aber die benutzerdefinierte Paginierung von Seiten über große Datenmengen wird effizienter, da nur die Datensätze abgerufen werden, die für eine bestimmte Seite angezeigt werden müssen.
Abbildung 17: Die Daten, die nach dem Namen des Produkts sortiert werden, werden mit benutzerdefiniertem Paging ausgelagert (Klicken Sie hier, um das bild in voller Größe anzuzeigen).
Hinweis
Beim benutzerdefinierten Paging wird der von ObjectDataSource SelectCountMethod
zurückgegebene Wert für die Seitenanzahl im Ansichtszustand von GridView gespeichert. Andere GridView-Variablen, die PageIndex
, EditIndex
, SelectedIndex
DataKeys
und so weiter, werden im Steuerelementzustand gespeichert, der unabhängig vom Wert der GridView-Eigenschaft EnableViewState
beibehalten wird. Da der PageCount
Wert über Postbacks hinweg mithilfe des Ansichtszustands beibehalten wird, ist es bei Verwendung einer Pagingschnittstelle mit einem Link zur letzten Seite zwingend erforderlich, dass der Ansichtsstatus von GridView aktiviert wird. (Wenn Ihre Pagingschnittstelle keinen direkten Link zur letzten Seite enthält, können Sie den Ansichtsstatus deaktivieren.)
Das Klicken auf den Link der letzten Seite führt zu einem Postback und weist die GridView an, seine PageIndex
Eigenschaft zu aktualisieren. Wenn auf den letzten Seitenlink geklickt wird, weist gridView seine PageIndex
Eigenschaft einem Wert zu, der unter der PageCount
Eigenschaft liegt. Wenn der Ansichtszustand deaktiviert ist, geht der PageCount
Wert über Postbacks hinweg verloren, und dem PageIndex
wird stattdessen der maximale ganzzahlige Wert zugewiesen. Als Nächstes versucht GridView, den Anfangszeilenindex zu bestimmen, indem die PageSize
Eigenschaften und PageCount
multipliziert werden. Dies führt zu einer OverflowException
, da das Produkt die maximal zulässige ganzzahlige Größe überschreitet.
Implementieren von benutzerdefiniertem Paging und Sortieren
Für die aktuelle Implementierung des benutzerdefinierten Pagings muss die Reihenfolge, in der die Daten ausgelagert werden, beim Erstellen der GetProductsPaged
gespeicherten Prozedur statisch angegeben werden. Möglicherweise haben Sie jedoch bemerkt, dass das Smarttag von GridView zusätzlich zur Option Paging aktivieren ein Kontrollkästchen Sortierung aktivieren enthält. Leider sortiert das Hinzufügen der Sortierunterstützung zur GridView mit unserer aktuellen benutzerdefinierten Pagingimplementierung nur die Datensätze auf der aktuell angezeigten Datenseite. Wenn Sie beispielsweise gridView so konfigurieren, dass es auch Paging unterstützt und dann beim Anzeigen der ersten Datenseite nach Produktname in absteigender Reihenfolge sortiert wird, wird die Reihenfolge der Produkte auf Seite 1 umgekehrt. Wie Abbildung 18 zeigt, zeigt diese Carnarvon Tigers als erstes Produkt bei der Sortierung in umgekehrter alphabetischer Reihenfolge, die die 71 anderen Produkte, die nach Carnarvon Tigers kommen, alphabetisch ignoriert; nur die Datensätze auf der ersten Seite werden bei der Sortierung berücksichtigt.
Abbildung 18: Nur die auf der aktuellen Seite angezeigten Daten sind sortiert (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Die Sortierung gilt nur für die aktuelle Datenseite, da die Sortierung erfolgt, nachdem die Daten aus der BLL-Methode GetProductsPaged
abgerufen wurden, und diese Methode nur diese Datensätze für die bestimmte Seite zurückgibt. Um die Sortierung ordnungsgemäß zu implementieren, müssen wir den Sortierausdruck an die GetProductsPaged
-Methode übergeben, damit die Daten entsprechend sortiert werden können, bevor die bestimmte Datenseite zurückgegeben wird. Wie Sie dies erreichen, erfahren Sie in unserem nächsten Tutorial.
Implementieren des benutzerdefinierten Pagings und Löschens
Wenn Sie die Löschfunktion in einer GridView aktivieren, deren Daten mit benutzerdefinierten Pagingtechniken ausgelagert werden, werden Sie feststellen, dass beim Löschen des letzten Datensatzes von der letzten Seite die GridView-Datei nicht entsprechend dekrementiert PageIndex
wird. Um diesen Fehler zu reproduzieren, aktivieren Sie das Löschen für das soeben erstellte Tutorial. Wechseln Sie zur letzten Seite (Seite 9), auf der Sie ein einzelnes Produkt sehen sollten, da wir 81 Produkte und 10 Produkte gleichzeitig durchlaufen. Löschen Sie dieses Produkt.
Beim Löschen des letzten Produkts sollte die GridView automatisch auf die achte Seite wechseln, und diese Funktionalität wird mit standard paging angezeigt. Beim benutzerdefinierten Paging wird gridView nach dem Löschen des letzten Produkts auf der letzten Seite jedoch ganz vom Bildschirm entfernt. Der genaue Grund , warum dies geschieht, liegt etwas außerhalb des Rahmens dieses Tutorials. Informationen zur Ursache dieses Problems finden Sie unter Löschen des letzten Datensatzes auf der letzten Seite aus einer GridView mit benutzerdefiniertem Paging . Zusammenfassend ist dies auf die folgende Abfolge von Schritten zurückzuführen, die vom GridView ausgeführt werden, wenn auf die Schaltfläche Löschen geklickt wird:
- Löschen des Datensatzes
- Abrufen der entsprechenden Datensätze, die für die angegebenen
PageIndex
undPageSize
- Überprüfen Sie, ob die
PageIndex
Anzahl der Datenseiten in der Datenquelle nicht überschritten wird. Wenn dies der Fall ist, wird die GridView-EigenschaftPageIndex
automatisch verringert. - Binden Sie die entsprechende Datenseite mithilfe der in Schritt 2 abgerufenen Datensätze an gridView.
Das Problem ergibt sich aus der Tatsache, dass in Schritt 2 die beim Abrufen der PageIndex
anzuzeigenden Datensätze verwendet wird, immer noch die PageIndex
der letzten Seite ist, deren einziger Datensatz gerade gelöscht wurde. Daher werden in Schritt 2 keine Datensätze zurückgegeben, da diese letzte Datenseite keine Datensätze mehr enthält. Dann erkennt die GridView in Schritt 3, dass seine PageIndex
Eigenschaft größer ist als die Gesamtzahl der Seiten in der Datenquelle (da wir den letzten Datensatz auf der letzten Seite gelöscht haben) und dekrementiert daher seine PageIndex
Eigenschaft. In Schritt 4 versucht gridView, sich an die in Schritt 2 abgerufenen Daten zu binden. in Schritt 2 wurden jedoch keine Datensätze zurückgegeben, was zu einer leeren GridView führt. Beim Standard paging tritt dieses Problem nicht auf, da in Schritt 2 alle Datensätze aus der Datenquelle abgerufen werden.
Um dies zu beheben, haben wir zwei Optionen. Die erste besteht darin, einen Ereignishandler für den GridView-Ereignishandler RowDeleted
zu erstellen, der bestimmt, wie viele Datensätze auf der Seite angezeigt wurden, die gerade gelöscht wurde. Wenn es nur einen Datensatz gab, muss der soeben gelöschte Datensatz der letzte gewesen sein, und wir müssen die GridView s PageIndex
dekrementieren. Natürlich möchten wir nur aktualisieren, wenn der PageIndex
Löschvorgang tatsächlich erfolgreich war. Dies kann bestimmt werden, indem Sie sicherstellen, dass die e.Exception
-Eigenschaft ist null
.
Dieser Ansatz funktioniert, da die PageIndex
nach Schritt 1, aber vor Schritt 2 aktualisiert wird. Daher wird in Schritt 2 der entsprechende Satz von Datensätzen zurückgegeben. Verwenden Sie hierzu Code wie folgt:
protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
// If we just deleted the last row in the GridView, decrement the PageIndex
if (e.Exception == null && GridView1.Rows.Count == 1)
// we just deleted the last row
GridView1.PageIndex = Math.Max(0, GridView1.PageIndex - 1);
}
Eine alternative Problemumgehung besteht darin, einen Ereignishandler für das ObjectDataSource-Ereignis RowDeleted
zu erstellen und die AffectedRows
Eigenschaft auf den Wert 1 festzulegen. Nach dem Löschen des Datensatzes in Schritt 1 (aber vor dem erneuten Abrufen der Daten in Schritt 2) aktualisiert gridView seine PageIndex
Eigenschaft, wenn eine oder mehrere Zeilen vom Vorgang betroffen waren. Die AffectedRows
-Eigenschaft wird jedoch nicht von ObjectDataSource festgelegt, und daher wird dieser Schritt weggelassen. Eine Möglichkeit, diesen Schritt auszuführen, besteht darin, die AffectedRows
Eigenschaft manuell festzulegen, wenn der Löschvorgang erfolgreich abgeschlossen wurde. Dies kann mithilfe von Code wie dem folgenden erreicht werden:
protected void ObjectDataSource1_Deleted(
object sender, ObjectDataSourceStatusEventArgs e)
{
// If we get back a Boolean value from the DeleteProduct method and it's true,
// then we successfully deleted the product. Set AffectedRows to 1
if (e.ReturnValue is bool && ((bool)e.ReturnValue) == true)
e.AffectedRows = 1;
}
Der Code für beide Ereignishandler befindet sich in der CodeBehind-Klasse des EfficientPaging.aspx
Beispiels.
Vergleich der Leistung von Standard- und benutzerdefinierter Paging
Da beim benutzerdefinierten Paging nur die erforderlichen Datensätze abgerufen werden, während das Standardpapageing alle Datensätze für jede angezeigte Seite zurückgibt, ist klar, dass benutzerdefinierte Paging effizienter ist als das Standardpapageing. Aber wie viel effizienter ist benutzerdefiniertes Paging? Welche Leistungssteigerungen können durch die Umstellung von standard paging zu benutzerdefiniertem Paging erzielt werden?
Leider gibt es hier keine einzige Größe, die für alle Antworten geeignet ist. Der Leistungsgewinn hängt von einer Reihe von Faktoren ab, wobei die beiden wichtigsten sind die Anzahl der Datensätze, die durchgelagert werden, und die Last, die auf dem Datenbankserver und den Kommunikationskanälen zwischen dem Webserver und dem Datenbankserver liegt. Bei kleinen Tabellen mit nur wenigen Dutzend Datensätzen kann der Leistungsunterschied vernachlässigbar sein. Bei großen Tabellen mit Tausenden bis Hunderttausenden von Zeilen ist der Leistungsunterschied jedoch akut.
Mein Artikel "Benutzerdefiniertes Paging in ASP.NET 2.0 mit SQL Server 2005" enthält einige Leistungstests, die ich ausgeführt habe, um die Leistungsunterschiede zwischen diesen beiden Pagingtechniken beim Durchlaufen einer Datenbanktabelle mit 50.000 Datensätzen zu zeigen. In diesen Tests habe ich sowohl die Zeit für die Ausführung der Abfrage auf SQL Server-Ebene (mithilfe von SQL Profiler) als auch auf der ASP.NET-Seite mit ASP.NET Ablaufverfolgungsfeatures untersucht. Denken Sie daran, dass diese Tests in meiner Entwicklungsbox mit einem einzelnen aktiven Benutzer ausgeführt wurden und daher unwissenschaftlich sind und keine typischen Websitelademuster nachahmen. Unabhängig davon veranschaulichen die Ergebnisse die relativen Unterschiede in der Ausführungszeit für standard- und benutzerdefinierte Paging bei der Arbeit mit ausreichend großen Datenmengen.
Durchschnittliche Dauer (Sek.) | Reads | |
---|---|---|
SQL-Profiler für Standard paging | 1.411 | 383 |
Benutzerdefinierter SQL-Profiler für Paging | 0.002 | 29 |
Standard paging ASP.NET Ablaufverfolgung | 2.379 | N/V |
Benutzerdefiniertes Paging ASP.NET Ablaufverfolgung | 0.029 | N/V |
Wie Sie sehen, erforderte das Abrufen einer bestimmten Datenseite durchschnittlich 354 Lesevorgänge weniger und wurde in einem Bruchteil der Zeit abgeschlossen. Auf der ASP.NET Seite konnte die Seite in etwa 1/100 der Zeit gerendert werden, die beim Standardpapageing benötigt wurde.
Zusammenfassung
Standardpaging ist ein Cinch, um einfach das Kontrollkästchen Paging aktivieren im Smarttag des Datenwebsteuerelements zu implementieren, aber diese Einfachheit geht auf Kosten der Leistung. Beim Standardpapageing werden alle Datensätze zurückgegeben, wenn ein Benutzer eine beliebige Datenseite anfordert, auch wenn nur ein kleiner Teil davon angezeigt wird. Um diesen Leistungsaufwand zu bekämpfen, bietet ObjectDataSource eine alternative Pagingoption für benutzerdefiniertes Paging.
Während das benutzerdefinierte Paging die Leistungsprobleme der Standard paging verbessert, indem nur die Datensätze abgerufen werden, die angezeigt werden müssen, ist es wichtiger, benutzerdefiniertes Paging zu implementieren. Zunächst muss eine Abfrage geschrieben werden, die ordnungsgemäß (und effizient) auf die bestimmte Teilmenge der angeforderten Datensätze zugreift. Dies kann auf verschiedene Arten erreicht werden. In diesem Tutorial haben wir untersucht, SQL Server neue ROW_NUMBER()
Funktion von 2005 zu verwenden, um Ergebnisse zu bewerten, und dann nur die Ergebnisse zurückzugeben, deren Rangfolge innerhalb eines angegebenen Bereichs liegt. Darüber hinaus müssen wir ein Mittel hinzufügen, um die Gesamtzahl der Datensätze zu bestimmen, die ausgelagert werden. Nach dem Erstellen dieser DAL- und BLL-Methoden müssen wir auch die ObjectDataSource so konfigurieren, dass sie bestimmen kann, wie viele Datensätze insgesamt ausgelagert werden, und die Werte start Row Index und Maximum Rows ordnungsgemäß an die BLL übergeben können.
Die Implementierung des benutzerdefinierten Pagings erfordert zwar eine Reihe von Schritten und ist nicht annähernd so einfach wie das Standard paging, aber benutzerdefiniertes Paging ist eine Notwendigkeit, wenn ausreichend große Datenmengen durchlaufen werden. Wie die untersuchten Ergebnisse gezeigt haben, kann das benutzerdefinierte Paging die Renderzeit der ASP.NET Seite in Sekunden verkürzen und die Last auf dem Datenbankserver um eine oder mehrere Größenordnungen verkürzen.
Viel Spaß beim Programmieren!
Zum Autor
Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für