Freigeben über


Effizientes Auslagern von großen Datenmengen (VB)

von Scott Mitchell

PDF herunterladen

Die Standardauslagerungsoption eines Datenpräsentationssteuerelements ist für die 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 beschrieben, kann Paging auf zwei Arten implementiert werden:

  • Standard paging kann implementiert werden, indem einfach die Option Paging aktivieren im Smarttag des Datenwebsteuerelements aktiviert wird. Wenn jedoch eine Seite mit Daten angezeigt wird, ruft ObjectDataSource alle Datensätze ab, obwohl nur eine Teilmenge von ihnen auf der Seite angezeigt wird.
  • Benutzerdefiniertes Paging verbessert die Leistung des Standardauslagerungs, indem nur die Datensätze aus der Datenbank abgerufen werden, die für die bestimmte Seite der vom Benutzer angeforderten Daten angezeigt werden müssen. Benutzerdefiniertes Paging erfordert jedoch etwas mehr Aufwand als standard paging.

Aufgrund der einfachen Implementierung aktivieren Sie einfach ein Kontrollkästchen und Sie sind fertig! Das Standard paging ist eine attraktive Option. Der naive Ansatz beim Abrufen aller Datensätze macht es jedoch zu einer unglaubwürdigen Wahl, wenn ausreichend große Datenmengen oder websites mit vielen gleichzeitigen Benutzern durchlaufen. Unter solchen Umständen müssen wir uns dem benutzerdefinierten Paging zuwenden, um ein reaktionsfähiges System bereitzustellen.

Die Herausforderung des benutzerdefinierten Pagings besteht darin, eine Abfrage zu schreiben, 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 der Datensätze effizient abrufen kann. In diesem Tutorial erfahren Sie, wie Sie diese neue SQL Server 2005 Schlüsselwort (keyword) verwenden, um benutzerdefiniertes Paging in einem GridView-Steuerelement zu implementieren. Während die Benutzeroberfläche für benutzerdefinierte Paging mit der benutzerdefinierten Paging-Benutzeroberfläche identisch ist, kann das Schrittweisen von einer Seite zur nächsten mithilfe von benutzerdefiniertem Paging mehrere Größenordnungen schneller sein als standard paging.

Hinweis

Die genaue Leistungssteigerung durch benutzerdefiniertes Paging hängt von der Gesamtzahl der Datensätze ab, die ausgelagert 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 zeigen, die durch benutzerdefiniertes Paging erzielt werden.

Schritt 1: Grundlegendes zum benutzerdefinierten Pagingprozess

Beim Auslagern 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 produkte 1 bis 10; wenn wir die zweite Seite sehen, 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 Pro-Seite anzuzeigenden Datensätzen multipliziert und hinzugefügt wird. Wenn Sie beispielsweise Datensätze 10 gleichzeitig durchlaufen, ist der Zeilenindex 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.
  • Maximum Rows : 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 durchlaufen, 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.
  • Datensatz 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 Paging-Schnittstelle neun Seitenzahlen auf der Paging-Benutzeroberfläche anzeigen.

Bei der Standard paging wird der Zeilenindex starten als Produkt des Seitenindexes und der Seitengröße plus eins berechnet, während maximale Zeilen einfach die Seitengröße ist. Da beim Standardpapageing beim Rendern von Datenseiten alle Datensätze aus der Datenbank abgerufen werden, ist der Index für jede Zeile bekannt, sodass der Wechsel zur Zeile Zeilenindex starten zu einer trivialen Aufgabe wird. 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 am Zeilenindex starten und danach bis zur maximalen Zeilenanzahl von Datensätzen beginnen. Das benutzerdefinierte Paging bietet zwei Herausforderungen:

  • Wir müssen in der Lage sein, jeder Zeile in den ausgelagerten Daten einen Zeilenindex effizient zuzuordnen, damit wir mit der Rückgabe von Datensätzen am angegebenen Startzeilenindex beginnen können.
  • Wir müssen die Gesamtzahl der Datensätze angeben, die ausgelagert werden.

In den nächsten beiden Schritten untersuchen wir das SQL-Skript, das für die Reaktion auf diese beiden Herausforderungen erforderlich ist. Zusätzlich zum SQL-Skript müssen wir auch Methoden in DAL und BLL implementieren.

Schritt 2: Zurückgeben der Gesamtanzahl der Datensätze, die ausgelagert werden

Bevor wir untersuchen, wie die genaue Teilmenge der Datensätze für die angezeigte Seite abgerufen wird, sehen wir uns zunächst an, wie die Gesamtanzahl der Datensätze zurückgegeben wird, die ausgelagert werden. Diese Informationen werden benötigt, um die Benutzeroberfläche des Pagings ordnungsgemäß zu konfigurieren. Die Gesamtanzahl von Datensätzen, die von einer bestimmten SQL-Abfrage zurückgegeben werden, 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 Wir 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 im Designer mit der rechten Maustaste auf die ProductsTableAdapter , und wählen Sie Abfrage hinzufügen aus. Wie wir in den vorherigen Tutorials gesehen haben, können wir dadurch dem 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 eine Ad-hoc-SQL-Anweisung.

Verwenden einer Ad-hoc-SQL-Anweisung

Abbildung 1: Verwenden einer Ad-hoc-SQL-Anweisung

Auf dem nächsten Bildschirm können wir angeben, welche Art von Abfrage erstellt werden soll. Da diese Abfrage einen einzelnen skalaren Wert zurückgibt, wählt die Gesamtzahl der Datensätze in der Products Tabelle die Option aus, die SELECT eine Singe-Wert-Option zurückgibt.

Konfigurieren der Abfrage für die Verwendung einer SELECT-Anweisung, die einen einzelnen Wert zurückgibt

Abbildung 2: Konfigurieren der Abfrage zur Verwendung einer SELECT-Anweisung, die einen einzelnen Wert zurückgibt

Nachdem der Typ der zu verwendenden Abfrage angegeben wurde, müssen wir als Nächstes die Abfrage angeben.

Verwenden der SELECT COUNT(*) FROM Products-Abfrage

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 TotalNumberOfProductswir .

Nennen Sie die DAL-Methode TotalNumberOfProducts.

Abbildung 4: Benennen der DAL-Methode TotalNumberOfProducts

Nachdem Sie auf Fertig stellen geklickt haben, fügt der Assistent die TotalNumberOfProducts -Methode der DAL hinzu. Die skalaren Rückgabemethoden im DAL geben Nullable-Typen zurück, falls das Ergebnis der SQL-Abfrage ist NULL. Unsere COUNT Abfrage gibt jedoch immer einen Nicht-Wert zurück. Unabhängig davon gibt die DAL-MethodeNULL eine ganze Zahl zurück, die nullwertefähig ist.

Neben der 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 s-Methode TotalNumberOfProducts aufruft:

Public Function TotalNumberOfProducts() As Integer
    Return Adapter.TotalNumberOfProducts().GetValueOrDefault()
End Function

Die DAL s-Methode TotalNumberOfProducts gibt eine ganze Zahl zurück, die NULL-Werte zulässt. Wir haben jedoch die ProductsBLL Klasse s-Methode TotalNumberOfProducts erstellt, sodass sie eine Standard-Ganzzahl zurückgibt. Daher muss die ProductsBLL Klasse s-Methode TotalNumberOfProducts den Wertteil der nullablen ganzen Zahl zurückgeben, die von der DAL s-Methode TotalNumberOfProducts zurückgegeben wird. Der Aufruf von GetValueOrDefault() gibt den Wert der nullablen ganzzahligen Zahl zurück, sofern vorhanden. Wenn die Nullable-Ganzzahl ist, gibt nullsie jedoch den standardwertlichen ganzzahligen Wert 0 zurück.

Schritt 3: Zurückgeben der genauen Teilmenge von Datensätzen

Unsere nächste Aufgabe besteht darin, Methoden in der DAL und BLL zu erstellen, die die zuvor besprochenen Variablen Zeilenindex starten und maximale Zeilen akzeptieren 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 ausgelagerten Ergebnissen effizient einen Index zuzuweisen, sodass wir nur die Datensätze zurückgeben können, die am Zeilenindex starten (und bis zur maximalen Datensatzanzahl von Datensätzen).

Dies ist keine Herausforderung, wenn bereits eine Spalte in der Datenbanktabelle vorhanden ist, die als Zeilenindex dient. Auf den ersten Blick könnte man denken, dass das Feld der ProductsProductID Tabelle ausreichen würde, da das erste Produkt ProductID 1 hat, das zweite eine 2 usw. Das Löschen eines Produkts hinterlässt jedoch eine Lücke in der Sequenz, wodurch dieser Ansatz auf null gesetzt wird.

Es gibt zwei allgemeine Techniken, die verwendet werden, um einen Zeilenindex effizient mit den Daten zu verknüpfen, die ausgelagert werden sollen, wodurch die genaue Teilmenge der Datensätze abgerufen werden kann:

  • Mit SQL Server 2005 s ROW_NUMBER() Schlüsselwort neu SQL Server 2005 ordnet die ROW_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 verarbeiten soll, bevor sie beendet wird. 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 (während der ROW_NUMBER() Ansatz nur mit SQL Server 2005 funktioniert).

    Die Idee besteht darin, eine Tabellenvariable zu erstellen, die über eine IDENTITY Spalte und Spalten für die Primärschlüssel der Tabelle verfügt, 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 die IDENTITY Spalte) zugeordnet wird. Nachdem die Tabellenvariable aufgefüllt wurde, kann eine SELECT Anweisung für die Tabellenvariable ausgeführt werden, die mit der zugrunde liegenden Tabelle verknüpft ist, um die bestimmten Datensätze herauszuziehen. Die SET ROWCOUNT -Anweisung wird verwendet, um die Anzahl der Datensätze, die in der Tabellenvariablen gespeichert werden müssen, intelligent zu begrenzen.

    Dieser Ansatz basiert auf der angeforderten Seitenzahl, da dem SET ROWCOUNT Wert der Wert Start Row Index plus Maximum Rows zugewiesen wird. Beim Paginieren von Seiten mit niedriger Nummerierung, z. B. den ersten Datenseiten, ist dieser Ansatz sehr effizient. Es weist jedoch eine standardmäßige Pagingleistung auf, wenn eine Seite am Ende abgerufen wird.

In diesem Tutorial wird das benutzerdefinierte Paging mithilfe der ROW_NUMBER() Schlüsselwort (keyword) implementiert. Weitere Informationen zur Verwendung der Tabellenvariablen und SET ROWCOUNT -technik finden Sie unter Eine effizientere Methode zum Paging durch große Resultsets.

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.

Der Preisrang ist für jeden zurückgegebenen Datensatz enthalten.

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()sowie den anderen Rangfolgefunktionen finden Sie in ROW_NUMBER Dokumentation.

Beim Rangieren der Ergebnisse nach der angegebenen ORDER BY Spalte in der OVER -Klausel (UnitPriceim 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 + MaximumRowsist.

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).

Hinzufügen einer neuen gespeicherten Prozedur für das Paging durch die Produkte

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@startRowIndexs 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.

Geben Sie einen Wert für die <span class=@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 .

Die Datensätze, die auf der zweiten Seite der Daten angezeigt werden, werden zurückgegeben.

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 , ProductsTableAdapterund 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.

Erstellen der DAL-Methode 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.

Wählen Sie die gespeicherte GetProductsPaged-Prozedur aus der liste der Drop-Down 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.

Angeben, dass die gespeicherte Prozedur tabellarische Daten zurückgibt

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.

Nennen Sie die Methoden FillPaged und 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 Function GetProductsPaged(startRowIndex As Integer, maximumRows As Integer) _
    As Northwind.ProductsDataTable
    Return Adapter.GetProductsPaged(startRowIndex, maximumRows)
End Function

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.

Konfigurieren der ObjectDataSource für die Verwendung der GetProductsPaged-Methode der ProductsBLL-Klasse

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.

Übernehmen Sie die Eingabeparameterquellen als Keine.

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 ProductNameBoundFields, CategoryNameSupplierName, , QuantityPerUnitund 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.

GridView wird nicht angezeigt.

Abbildung 15: GridView wird nicht angezeigt

GridView fehlt, da objectDataSource derzeit 0 als Werte für die GetProductsPagedstartRowIndex 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:

  1. Legen Sie die ObjectDataSource-Eigenschaft EnablePaging auf true fest, die an die ObjectDataSource übergeben wird, die an die SelectMethod beiden zusätzlichen Parameter übergeben werden muss: einer, um den Zeilenindex starten (StartRowIndexParameterName) anzugeben, und einer, um die maximale Zeilenanzahl (MaximumRowsParameterName) anzugeben.
  2. Legen Sie objectDataSource s StartRowIndexParameterName und MaximumRowsParameterName Properties fest Entsprechend geben die StartRowIndexParameterName Eigenschaften und MaximumRowsParameterName die Namen der Eingabeparameter an, die SelectMethod für benutzerdefinierte Pagingzwecke übergeben werden. Standardmäßig sind startIndexRow diese Parameternamen und maximumRows, weshalb ich beim Erstellen der GetProductsPaged Methode in der BLL diese Werte für die Eingabeparameter verwendet habe. Wenn Sie verschiedene Parameternamen für die BLL-Methode GetProductsPaged verwenden möchten, z startIndex . B. und maxRows, müssen Sie die ObjectDataSource-Eigenschaften StartRowIndexParameterName und MaximumRowsParameterName die Eigenschaften entsprechend festlegen (z. B. startIndex für StartRowIndexParameterName und maxRows für MaximumRowsParameterName).
  3. 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 der ProductsBLL Klasse s TotalNumberOfProducts die Gesamtanzahl der Datensätze zurückgibt, die ausgelagert werden, indem eine DAL-Methode verwendet wird, die eine SELECT COUNT(*) FROM Products Abfrage ausführt. Diese Informationen werden von ObjectDataSource benötigt, um die Pagingschnittstelle ordnungsgemäß zu rendern.
  4. Entfernen Sie die startRowIndex Elemente und maximumRows<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 der GetProductsPaged Methode hinzugefügt. Wenn Sie auf truefestlegenEnablePaging, werden diese Parameter automatisch übergeben. Wenn sie auch in der deklarativen Syntax angezeigt werden, versucht objectDataSource, vier Parameter an die GetProductsPaged -Methode und zwei Parameter an die TotalNumberOfProducts -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}" SelectMethod="GetProductsPaged"
    TypeName="ProductsBLL" 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.

Konfigurieren Sie zum Verwenden des benutzerdefinierten Pagings das ObjectDataSource-Steuerelement

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.

Die Nach dem Namen des Produkts bestellten Daten werden mit benutzerdefiniertem Paging ausgelagert.

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, SelectedIndexDataKeys 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.

Nur die auf der aktuellen Seite angezeigten Daten werden sortiert.

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 PageIndexwird. 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:

  1. Löschen des Datensatzes
  2. Abrufen der entsprechenden Datensätze, die für die angegebenen PageIndex und PageSize
  3. Überprüfen Sie, ob die PageIndex Anzahl der Datenseiten in der Datenquelle nicht überschritten wird. Wenn dies der Fall ist, wird die GridView-Eigenschaft PageIndex automatisch verringert.
  4. 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 PageIndexdekrementieren. 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 Sub GridView1_RowDeleted(sender As Object, e As GridViewDeletedEventArgs) _
    Handles GridView1.RowDeleted
    ' If we just deleted the last row in the GridView, decrement the PageIndex
    If e.Exception Is Nothing AndAlso GridView1.Rows.Count = 1 Then
        ' we just deleted the last row
        GridView1.PageIndex = Math.Max(0, GridView1.PageIndex - 1)
    End If
End Sub

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 Sub ObjectDataSource1_Deleted( _
    sender As Object, e As ObjectDataSourceStatusEventArgs) _
    Handles ObjectDataSource1.Deleted
    ' 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 TypeOf e.ReturnValue Is Boolean AndAlso CType(e.ReturnValue, Boolean) = True Then
        e.AffectedRows = 1
    End If
End Sub

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.