Freigeben über


Effizientes Auslagern von großen Datenmengen (C#)

von Scott Mitchell

PDF herunterladen

Die Standardauslagerungsoption eines Datenpräsentationssteuerelements ist beim Arbeiten mit großen Datenmengen ungeeignet, da das zugrunde liegende Datenquellensteuerelement alle Datensätze abruft, obwohl nur eine Teilmenge von Daten angezeigt wird. Unter solchen Umständen müssen wir uns an die benutzerdefinierte Seitenverwaltung wenden.

Einführung

Wie im vorherigen Lernprogramm erläutert, kann paging auf eine von zwei Arten implementiert werden:

  • Standardmäßiges Paging kann implementiert werden, indem einfach die Option "Paging aktivieren" im Smarttag des Datenwebsteuerelements überprüft wird. Bei der Anzeige einer Datenseite ruft die ObjectDataSource jedoch alle Datensätze ab, obwohl nur eine Teilmenge auf der Seite angezeigt wird.
  • Benutzerdefiniertes Paging verbessert die Leistung der Standard paging , 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. Benutzerdefinierte Paging erfordert jedoch etwas mehr Aufwand, um dies zu implementieren als die Standard paging.

Aufgrund der einfachen Implementierung aktivieren Sie einfach ein Kontrollkästchen, und Sie sind fertig! Standard paging ist eine attraktive Option. Sein naiver Ansatz beim Abrufen aller Datensätze macht es jedoch zu einer unerschöpflichen Wahl, wenn sie über ausreichend große Datenmengen oder für Websites mit vielen gleichzeitigen Benutzern auslagerungen. Unter solchen Umständen müssen wir uns an eine benutzerdefinierte Paging wenden, um ein reaktionsfähiges System bereitzustellen.

Die Herausforderung der benutzerdefinierten Seitenverwaltung 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 stellt Microsoft SQL Server 2005 ein neues Schlüsselwort für Bewertungsergebnisse bereit, mit dem wir eine Abfrage schreiben können, mit der die richtige Teilmenge von Datensätzen effizient abgerufen werden kann. In diesem Lernprogramm erfahren Sie, wie Sie dieses neue SQL Server 2005-Schlüsselwort verwenden, um benutzerdefinierte Paging in einem GridView-Steuerelement zu implementieren. Die Benutzeroberfläche für benutzerdefinierte Paging ist zwar identisch mit dem für die Standard paging, aber das Wechseln von einer Seite zur nächsten mithilfe benutzerdefinierter Pagings kann mehrere Größenordnungen schneller sein als die Standard paging.

Hinweis

Die genaue Leistungssteigerung, die von der benutzerdefinierten Auslagerung ausgestellt wird, hängt von der Gesamtzahl der Datensätze ab, die durchsucht werden, und der Last, die auf dem Datenbankserver platziert wird. Am Ende dieses Lernprogramms sehen wir uns einige grobe Metriken an, die die Vorteile der Leistung zeigen, die durch benutzerdefinierte Paging erzielt werden.

Schritt 1: Grundlegendes zum benutzerdefinierten Pagingprozess

Beim Ausblättern durch Daten hängen die genauen Datensätze, die auf einer Seite angezeigt werden, von der angeforderten Datenseite und der Anzahl der pro Seite angezeigten Datensätze ab. Stellen Sie sich z. B. vor, dass wir die 81 Produkte durchblättern wollten, wobei 10 Produkte pro Seite angezeigt werden. Beim Anzeigen der ersten Seite möchten wir produkte 1 bis 10; Bei der Anzeige der zweiten Seite interessieren wir uns für Produkte von 11 bis 20 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; this index can be calculated by the page index by the records to display per page and adding one. Wenn Sie beispielsweise die Datensätze 10 gleichzeitig durchlaufen, für die erste Seite (deren Seitenindex 0 ist), lautet der Zeilenindex "Anfang" 0 * 10 + 1 oder 1; für die zweite Seite (deren Seitenindex 1 ist), ist der Zeilenindex "Start" 1 * 10 + 1 oder 11.
  • 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 z. B. die 81 Produkte 10 Datensätze pro Seite durchlaufen, hat die neunte und letzte Seite nur einen Datensatz. Auf keiner Seite werden jedoch mehr Datensätze als der Wert für maximale Zeilen angezeigt.
  • Gesamtanzahl der Datensätze, durch die die Gesamtzahl der Datensätze ausgelagert wird. Diese Variable ist zwar nicht erforderlich, um zu bestimmen, welche Datensätze für eine bestimmte Seite abgerufen werden sollen, aber sie diktieren die Pagingschnittstelle. Wenn beispielsweise 81 Produkte durchlaufen werden, weiß die Seitenschnittstelle neun Seitenzahlen in der Seiten-UI anzuzeigen.

Bei der Standardmäßigen Auslagerung wird der Startzeilenindex als Produkt des Seitenindex und des Seitenformats plus eins berechnet, während die maximale Zeilen einfach die Seitengröße ist. Da die Standardauflagerung beim Rendern einer Beliebigen Datenseite alle Datensätze aus der Datenbank abruft, wird der Index für jede Zeile bekannt, wodurch der Wechsel zur Zeile "Zeilenanfang" zu einer trivialen Aufgabe wird. Darüber hinaus ist die Gesamtzahl der Datensätze leicht verfügbar, da sie einfach die Anzahl der Datensätze in der DataTable (oder das Objekt, das zum Speichern der Datenbankergebnisse verwendet wird) ist.

Angesichts der Variablen "Zeilenindex anfang" und "Maximale Zeilen" darf eine benutzerdefinierte Pagingimplementierung nur die genaue Teilmenge von Datensätzen zurückgeben, die am Anfang des Zeilenindex beginnen und bis zur maximalen Zeilenanzahl von Datensätzen danach. Benutzerdefinierte Paging bietet zwei Herausforderungen:

  • Wir müssen einen Zeilenindex effizient jeder Zeile in den gesamten Daten zuordnen können, die ausgelagert werden, damit wir mit der Rückgabe von Datensätzen am angegebenen Startzeilenindex beginnen können.
  • Wir müssen die Gesamtanzahl der Datensätze angeben, über die seitent wird

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 DAL und BLL implementieren.

Schritt 2: Zurückgeben der Gesamtanzahl der Datensätze, durch die seitent wird

Bevor wir untersuchen, wie die genaue Teilmenge von Datensätzen für die angezeigte Seite abgerufen wird, sehen wir uns zunächst an, wie die Gesamtanzahl der Datensätze zurückgegeben wird, die durchsucht werden. Diese Informationen werden benötigt, 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 Gesamtanzahl der Datensätze in der Products Tabelle zu ermitteln, 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, die die TotalNumberOfProducts() oben gezeigte SELECT Anweisung ausführt.

Öffnen Sie zunächst die Northwind.xsd Typed DataSet-Datei im App_Code/DAL Ordner. Klicken Sie als Nächstes mit der rechten Maustaste auf den ProductsTableAdapter Designer, und wählen Sie "Abfrage hinzufügen" aus. Wie wir in früheren Lernprogrammen gesehen haben, können wir 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 früheren Lernprogrammen entscheiden sie sich für diese Methode für die Verwendung einer 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, wird die Gesamtanzahl der Datensätze in der Products Tabelle ausgewählt, die eine SELECT Option für einen singe-Wert zurückgibt.

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

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

Nachdem der typ der zu verwendenden Abfrage angegeben wurde, müssen wir die Abfrage als nächstes 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 .

Benennen der DAL-Methode TotalNumberOfProducts

Abbildung 4: Benennen der DAL-Methode TotalNumberOfProducts

Nachdem Sie auf "Fertig stellen" geklickt haben, fügt der Assistent die TotalNumberOfProducts Methode dem DAL hinzu. Die skalaren Rückgabemethoden in den DAL-Rückgabe-Null-Typen, falls das Ergebnis aus 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.

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

public int TotalNumberOfProducts()
{
    return Adapter.TotalNumberOfProducts().GetValueOrDefault();
}

Die DAL s-Methode TotalNumberOfProducts gibt eine nullable ganze Zahl zurück. Wir haben jedoch die Methode der ProductsBLL Klasse TotalNumberOfProducts erstellt, sodass sie eine standardzahlige Zahl zurückgibt. Daher müssen wir die Klasse TotalNumberOfProducts s-Methode ProductsBLL den Wertteil der nullablen ganzen Zahl zurückgeben, die von der DAL s-Methode TotalNumberOfProducts zurückgegeben wird. Der Aufruf, um GetValueOrDefault() den Wert der nullablen ganzzahligen Zahl zurückgibt, sofern vorhanden. Wenn die nullable ganze Zahl ist null, wird jedoch der Standardwert für ganze Zahlen 0 zurückgegeben.

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

Unsere nächste Aufgabe besteht darin, Methoden in dal und BLL zu erstellen, die die zuvor behandelten Variablen "Anfang Zeile Index" und "Maximale Zeilen" akzeptieren und die entsprechenden Datensätze zurückgeben. Bevor wir dies tun, sehen wir uns zuerst das erforderliche SQL-Skript an. Die Herausforderung besteht darin, dass wir in der Lage sein müssen, jeder Zeile in den gesamten Ergebnissen, die ausgelagert werden, effizient einen Index zuzuweisen, sodass wir nur diese Datensätze zurückgeben können, die beim Startzeilenindex (und bis zur Maximalen Datensatzanzahl von Datensätzen) beginnen.

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

Es gibt zwei allgemeine Techniken, die verwendet werden, um einen Zeilenindex effizient mit den Daten zu verknüpfen, durch die die genauen Teilmengen von Datensätzen abgerufen werden können:

  • Mit sql Server 2005 s ROW_NUMBER() Keyword new to SQL Server 2005 verknüpft das ROW_NUMBER() Schlüsselwort eine Rangfolge mit jedem zurückgegebenen Datensatz basierend auf einer bestimmten Sortierung. Diese Rangfolge kann als Zeilenindex für jede Zeile verwendet werden.

  • Die Verwendung einer Table Variable- und SET ROWCOUNT SQL Server-AnweisungSET ROWCOUNT kann verwendet werden, um anzugeben, wie viele Datensätze eine Abfrage verarbeiten soll, bevor sie beendet werden. Tabellenvariablen sind lokale T-SQL-Variablen, die tabellarische Daten enthalten können, ähnlich wie temporäre Tabellen. Dieser Ansatz eignet sich gleichermaßen gut für Microsoft SQL Server 2005 und SQL Server 2000 (während der ROW_NUMBER() Ansatz nur mit SQL Server 2005 funktioniert).

    Die Idee ist hier, 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 die Tabellenvariable gedupt, wodurch ein sequenzieller Zeilenindex (über die IDENTITY Spalte) für jeden Datensatz in der Tabelle zugeordnet wird. Nachdem die Tabellenvariable aufgefüllt wurde, kann eine SELECT Anweisung für die Tabellenvariable, die mit der zugrunde liegenden Tabelle verknüpft ist, ausgeführt werden, um die jeweiligen Datensätze abzurufen. Die SET ROWCOUNT Anweisung wird verwendet, um die Anzahl der Datensätze, die in der Tabellenvariablen gedumpt werden müssen, intelligent zu begrenzen.

    Die Effizienz dieses Ansatzes basiert auf der angeforderten Seitenzahl, da dem SET ROWCOUNT Wert der Wert des Startzeilenindex plus der maximalen Zeilen zugewiesen wird. Bei der Auslagerung durch Seiten mit geringer Anzahl, wie z. B. die ersten Seiten mit Daten, ist dieser Ansatz sehr effizient. Es zeigt jedoch beim Abrufen einer Seite am Ende standardmäßige Paging-ähnliche Leistung an.

Dieses Lernprogramm implementiert benutzerdefinierte Paging mithilfe des ROW_NUMBER() Schlüsselworts. Weitere Informationen zur Verwendung der Tabellenvariable und SET ROWCOUNT -technik finden Sie unter Effizientes Paging über große Datenmengen.

Das ROW_NUMBER() Schlüsselwort zugeordnet eine Rangfolge mit jedem Datensatz, der über eine bestimmte Reihenfolge zurückgegeben wird, mithilfe der folgenden Syntax:

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. die Rangfolge für jedes Produkt anzuzeigen, das von den teuersten bis zum geringsten bestellt wurde, könnten 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 beim Ausführen des Abfragefensters in Visual Studio. 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 Bewertungsfunktionen, die in SQL Server 2005 verfügbar sind. Eine ausführlichere Erläuterung zu ROW_NUMBER()den anderen Bewertungsfunktionen finden Sie unter "Rückgabe bewerteter Ergebnisse" mit Microsoft SQL Server 2005.

Wenn die Ergebnisse nach der angegebenen ORDER BY Spalte in der OVER Klausel (UnitPriceim obigen Beispiel) sortiert werden, muss SQL Server die Ergebnisse sortieren. Dies ist ein schneller Vorgang, wenn es einen gruppierten Index über den Spalten gibt, nach denen die Ergebnisse sortiert werden, oder wenn ein abgedeckter Index vorhanden ist, aber 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. Weitere Informationen zu den Leistungsaspekten finden Sie unter Bewertungsfunktionen und Leistung in SQL Server 2005 .

Die von ihnen zurückgegebenen ROW_NUMBER() Bewertungsinformationen können nicht direkt in der WHERE Klausel verwendet werden. Eine abgeleitete Tabelle kann jedoch verwendet werden, um das ROW_NUMBER() Ergebnis zurückzugeben, das dann in der WHERE Klausel angezeigt werden kann. Die folgende Abfrage verwendet beispielsweise eine abgeleitete Tabelle, um die Spalten "ProductName" und "UnitPrice" zusammen mit dem ROW_NUMBER() Ergebnis zurückzugeben. Anschließend wird eine WHERE Klausel verwendet, 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 noch etwas weiter zu erweitern, können wir diesen Ansatz verwenden, um eine bestimmte Seite mit Daten abzurufen, die den gewünschten Anfangszeilenindex und die maximalen Zeilenwerte aufweisen:

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 weiter unten in diesem Lernprogramm sehen werden, wird die StartRowIndex von ObjectDataSource bereitgestellte Objektquelle beginnend mit 0 indiziert, während der ROW_NUMBER() von SQL Server 2005 zurückgegebene Wert ab 1 indiziert wird. Daher gibt die WHERE Klausel diese Datensätze zurück, bei denen PriceRank es streng größer als StartRowIndex und kleiner als oder gleich ist StartRowIndex + MaximumRows.

Nachdem wir nun erläutert haben, wie ROW_NUMBER() eine bestimmte Datenseite anhand der Werte "Anfang Zeile Index" und "Maximale Zeilen" abgerufen werden kann, müssen wir diese Logik jetzt als Methoden in 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 wir mit der implementierung der benutzerdefinierten Paging in diesem Lernprogramm keinen benutzerdefinierten seitenseitigen Bericht erstellen können, als auch sortiert werden können. Im nächsten Lernprogramm sehen wir jedoch, wie diese Funktionalität bereitgestellt werden kann.

Im vorherigen Abschnitt haben wir die DAL-Methode als Ad-hoc-SQL-Anweisung erstellt. Leider ähnelt der T-SQL-Parser in Visual Studio, der vom TableAdapter-Assistenten verwendet wird, nicht die 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" den Server-Explorer aus (oder drücken Sie STRG+ALT+S), und erweitern Sie den NORTHWND.MDF Knoten. Wenn Sie eine neue gespeicherte Prozedur hinzufügen möchten, klicken Sie 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 zum Auslagern der Produkte

Abbildung 6: Hinzufügen einer neuen gespeicherten Prozedur zum Auslagern der Produkte

Diese gespeicherte Prozedur sollte zwei ganzzahlige Eingabeparameter akzeptieren und @startRowIndex die vom Feld sortierte Funktion verwenden und nur diese Zeilen zurückgeben, die größer als die angegebene @startRowIndex und kleiner oder gleich s sind + @startRowIndex@maximumRow.ProductName ROW_NUMBER() @maximumRows 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 zu testen. Klicken Sie im Server-Explorer mit der rechten Maustaste auf den Namen der GetProductsPaged gespeicherten Prozedur, und wählen Sie die Option "Ausführen" aus. Visual Studio fordert Sie dann zur Eingabeparameter @startRowIndex und @maximumRow s auf (siehe Abbildung 7). Probieren Sie unterschiedliche Werte aus, und überprüfen Sie die Ergebnisse.

Geben Sie einen Wert für die klasse <span= ein.@startRowIndex und @maximumRows Parameter" />

Abbildung 7: Eingeben eines Werts für die und @maximumRows Die @startRowIndex Parameter

Nachdem Sie diese Eingabeparameterwerte ausgewählt haben, zeigt das Ausgabefenster die Ergebnisse an. Abbildung 8 zeigt die Ergebnisse beim Übergeben von 10 sowohl für die Parameter @maximumRows als auch für die @startRowIndex Parameter.

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, 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 typierte DataSet, klicken Sie mit der rechten Maustaste in das ProductsTableAdapterFeld, und wählen Sie die Option "Abfrage hinzufügen" aus. Statt 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 gespeicherte Prozedur auszuwählen, die aufgerufen werden soll. Wählen Sie die GetProductsPaged gespeicherte Prozedur aus der Dropdownliste aus.

Wählen Sie die gespeicherte Prozedur

Abbildung 10: Auswählen der gespeicherten GetProductsPaged-Prozedur aus der Dropdownliste

Im nächsten Bildschirm werden Sie 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 sie tabellarische Daten zurückgibt.

Gibt an, 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 erstellt haben möchten. Wie in unseren vorherigen Lernprogrammen können Sie Methoden sowohl mit der Datentabelle ausfüllen als auch mit der Rückgabe einer DataTable erstellen. Benennen Sie die erste Methode FillPaged und die zweite GetProductsPaged.

Benennen der Methoden FillPaged und GetProductsPaged

Abbildung 12: Benennen der Methoden FillPaged und GetProductsPaged

Zusätzlich zur Erstellung einer DAL-Methode zur Rückgabe einer bestimmten Seite von Produkten müssen wir auch solche Funktionen in der BLL bereitstellen. Wie bei der DAL-Methode muss die BLL-Methode GetProductsPaged zwei ganzzahlige Eingaben für die Angabe des Anfangszeilenindex 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, z. B.:

[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, wählen startRowIndex sie eine zusätzliche Arbeit aus, maximumRows wenn Sie eine ObjectDataSource für diese Methode konfigurieren.

Schritt 4: Konfigurieren der ObjectDataSource für die Verwendung von benutzerdefiniertem Paging

Mit den BLL- und DAL-Methoden für den Zugriff auf eine bestimmte Teilmenge von Datensätzen sind wir bereit, ein GridView-Steuerelement zu erstellen, das über die zugrunde liegenden Datensätze mithilfe von benutzerdefiniertem Paging seiten. Öffnen Sie zunächst die EfficientPaging.aspx Seite im PagingAndSorting Ordner, fügen Sie der Seite eine GridView hinzu, und konfigurieren Sie sie für die Verwendung eines neuen ObjectDataSource-Steuerelements. In unseren früheren Lernprogrammen hatten wir häufig die ObjectDataSource für die Verwendung der ProductsBLL Klassenmethode 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ückgegeben wird.

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 fordert der ObjectDataSource-Assistent uns zur Eingabe von Quellen der GetProductsPaged Methoden startRowIndex - und maximumRows Eingabeparameterwerte auf. Diese Eingabeparameter werden tatsächlich automatisch von gridView festgelegt, lassen Sie die Quelle also einfach auf "Keine" festgelegt, und klicken Sie auf "Fertig stellen".

Belassen der Eingabeparameterquellen als

Abbildung 14: Belassen der Eingabeparameterquellen als "Keine"

Nach Abschluss des ObjectDataSource-Assistenten enthält die GridView ein BoundField- oder CheckBoxField-Element für jedes der Produktdatenfelder. Sie können die Darstellung von GridView so anpassen, wie sie passen. Ich habe mich entschieden, nur die ProductName, , CategoryName, SupplierName, QuantityPerUnitund UnitPrice BoundFields anzuzeigen. Konfigurieren Sie außerdem die GridView so, dass paging unterstützt wird, indem Sie das Kontrollkästchen "Paging aktivieren" in ihrem Smarttag aktivieren. Nach diesen Änderungen sollte das deklarative Markup "GridView" und "ObjectDataSource" 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 besuchen, ist gridView nicht an der Stelle, an der sie gefunden werden können.

Die GridView wird nicht angezeigt.

Abbildung 15: Die GridView wird nicht angezeigt.

Die GridView fehlt, da die ObjectDataSource derzeit 0 als Werte für die GetProductsPaged startRowIndex Parameter und maximumRows Eingabeparameter verwendet. Daher gibt die resultierende SQL-Abfrage keine Datensätze zurück und daher wird die GridView nicht angezeigt.

Um dies zu beheben, müssen wir die ObjectDataSource so konfigurieren, dass benutzerdefinierte Paging verwendet wird. Dies kann in den folgenden Schritten durchgeführt werden:

  1. Legen Sie die ObjectDataSource-Eigenschaft EnablePaging so true fest, dass sie an die ObjectDataSource übergeben werden muss, um die SelectMethod beiden zusätzlichen Parameter anzugeben: einen, um den Startzeilenindex (StartRowIndexParameterName) anzugeben, und eine, um die maximale Zeile (MaximumRowsParameterName) anzugeben.
  2. Legen Sie die ObjectDataSource-Elemente StartRowIndexParameterName und MaximumRowsParameterName -Eigenschaften entsprechend fest, und die MaximumRowsParameterName StartRowIndexParameterName Eigenschaften geben die Namen der Eingabeparameter an, die SelectMethod für benutzerdefinierte Auslagerungszwecke ü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 unterschiedliche Parameternamen für die BLL-Methode wie z. B. und maxRows, z. B. verwenden möchten, müssen Sie die ObjectDataSource s StartRowIndexParameterName und MaximumRowsParameterName Eigenschaften entsprechend festlegen (z. B. startIndex für StartRowIndexParameterName und maxRows für MaximumRowsParameterName).startIndex GetProductsPaged
  3. Legen Sie die ObjectDataSource s-Eigenschaft SelectCountMethod auf den Namen der Methode fest, die die Gesamtanzahl der Datensätze zurückgibt, die paged Through (TotalNumberOfProducts) zurückgibt, dass die Methode der ProductsBLL Klasse TotalNumberOfProducts die Gesamtzahl der Datensätze zurückgibt, die mithilfe einer DAL-Methode, die eine SELECT COUNT(*) FROM Products Abfrage ausführt, ausgelagert werden. Diese Informationen werden von ObjectDataSource benötigt, um die Paging-Schnittstelle korrekt zu rendern.
  4. Entfernen Sie die startRowIndex Elemente aus<asp:Parameter> maximumRowsdem 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. Durch Festlegen EnablePaging auf true, 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' mit Parametern finden: startRowIndex, maximumRowRows.

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 und SelectCountMethod die EnablePaging Eigenschaften festgelegt wurden und die <asp:Parameter> Elemente entfernt wurden. Abbildung 16 zeigt einen Screenshot der Eigenschaftenfenster, nachdem diese Änderungen vorgenommen wurden.

So verwenden Sie benutzerdefiniertes Paging, konfigurieren Sie das ObjectDataSource-Steuerelement

Abbildung 16: Konfigurieren des ObjectDataSource-Steuerelements zum Verwenden von benutzerdefinierter Paging

Nachdem Sie diese Änderungen vorgenommen haben, besuchen Sie diese Seite über einen Browser. Es sollten 10 Produkte aufgelistet und alphabetisch sortiert werden. Nehmen Sie sich einen Moment Zeit, um die Daten einzeln zu durchlaufen. Obwohl es keinen visuellen Unterschied zwischen der Perspektive des Endbenutzers zwischen Standard paging und benutzerdefiniertem Paging gibt, werden benutzerdefinierte Auslagerungen effizienter durch große Datenmengen durchlaufen, da nur diese Datensätze abgerufen werden, die für eine bestimmte Seite angezeigt werden müssen.

Die nach dem Produktnamen sortierten Daten werden mithilfe einer benutzerdefinierten Paging-Seite geordnet.

Abbildung 17: Die Daten, sortiert nach dem Namen des Produkts, werden mit benutzerdefiniertem Paging seitengesteuert (Klicken Sie, um das Bild mit voller Größe anzuzeigen)

Hinweis

Bei benutzerdefinierter Auslagerung wird der von objectDataSource SelectCountMethod zurückgegebene Seitenanzahlswert im Ansichtszustand von GridView gespeichert. Andere GridView-Variablen werden unabhängig PageIndexEditIndexDataKeys SelectedIndexvom Wert der GridView-Eigenschaft EnableViewState im Steuerelementzustand gespeichert. Da der PageCount Wert über Postbacks hinweg mithilfe des Ansichtszustands beibehalten wird, ist es zwingend erforderlich, dass der Ansichtszustand von GridView aktiviert wird, wenn eine Pagingschnittstelle verwendet wird, die einen Link enthält, der Sie zur letzten Seite bringt. (Wenn Ihre Paging-Schnittstelle keinen direkten Link zur letzten Seite enthält, können Sie den Ansichtszustand deaktivieren.)

Durch Klicken auf den letzten Seitenlink wird ein Postback verursacht und die GridView angewiesen, seine PageIndex Eigenschaft zu aktualisieren. Wenn auf den letzten Seitenlink geklickt wird, weist das GridView seine PageIndex Eigenschaft einem Wert zu, der kleiner als seine PageCount Eigenschaft ist. Wenn der Ansichtszustand deaktiviert ist, geht der PageCount Wert über Postbacks hinweg verloren, und dem PageIndex Wert wird stattdessen der maximale ganzzahlige Wert zugewiesen. Als Nächstes versucht gridView, den Anfangszeilenindex durch Multiplizieren der PageSize PageCount Eigenschaften zu bestimmen. Dies führt dazu OverflowException , dass das Produkt die maximal zulässige ganzzahlige Größe überschreitet.

Implementieren von benutzerdefiniertem Paging und Sortieren

Unsere aktuelle implementierung für benutzerdefinierte Paging erfordert, dass die Reihenfolge, in der die Daten beim Erstellen der GetProductsPaged gespeicherten Prozedur statisch durchlaufen werden, angegeben werden. Möglicherweise haben Sie jedoch bemerkt, dass das Smarttag "GridView" zusätzlich zur Option "Paging aktivieren" ein Kontrollkästchen "Sortierung aktivieren" enthält. Leider werden beim Hinzufügen der Sortierunterstützung zu GridView mit unserer aktuellen benutzerdefinierten Pagingimplementierung nur die Datensätze auf der aktuell angezeigten Datenseite sortiert. Wenn Sie z. B. die GridView so konfigurieren, dass das Paging unterstützt wird, und wenn Sie die erste Datenseite anzeigen, sortieren Sie nach Produktname in absteigender Reihenfolge, wird die Reihenfolge der Produkte auf Seite 1 umgekehrt. Wie Abbildung 18 zeigt, zeigt carnarvon Tigers als erstes Produkt bei der Sortierung in umgekehrter alphabetischer Reihenfolge, die die 71 anderen Produkte ignoriert, die nach Carnarvon Tigers kommen, alphabetisch; Nur die Datensätze auf der ersten Seite werden in der Sortierung berücksichtigt.

Nur die auf der aktuellen Seite angezeigten Daten sind sortiert.

Abbildung 18: Nur die auf der aktuellen Seite angezeigten Daten sind sortiert (Zum Anzeigen des Bilds mit voller Größe klicken)

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 gibt nur diese Datensätze für die jeweilige Seite zurück. Um die Sortierung korrekt zu implementieren, müssen wir den Sortierausdruck an die GetProductsPaged Methode übergeben, damit die Daten entsprechend bewertet werden können, bevor die spezifische Datenseite zurückgegeben wird. In unserem nächsten Lernprogramm erfahren Sie, wie Sie dies erreichen können.

Implementieren von benutzerdefiniertem Paging und Löschen

Wenn Sie das Löschen von Funktionen 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 das GridView-Objekt PageIndexnicht mehr ordnungsgemäß erhöht wird. Um diesen Fehler zu reproduzieren, aktivieren Sie das Löschen für das soeben erstellte Lernprogramm. Wechseln Sie zur letzten Seite (Seite 9), auf der Sie ein einzelnes Produkt sehen sollten, da wir 81 Produkte, 10 Produkte gleichzeitig ausgelagert haben. Dieses Produkt löschen.

Beim Löschen des letzten Produkts sollte gridView automatisch zur achten Seite wechseln, und diese Funktionalität wird mit standardseitigem Paging angezeigt. Bei der benutzerdefinierten Auslagerung wird das GridView-Element nach dem Löschen des letzten Produkts auf der letzten Seite jedoch einfach vollständig vom Bildschirm entfernt. Der genaue Grund , warum dies geschieht, liegt etwas außerhalb des Umfangs dieses Lernprogramms; siehe Löschen des letzten Datensatzes auf der letzten Seite aus einer GridView mit benutzerdefiniertem Paging für die Details auf niedriger Ebene in Bezug auf die Quelle dieses Problems. Zusammenfassend ist dies auf die folgende Abfolge der Schritte zurückzuführen, die von 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 angegebene Anzeige angezeigt PageIndex werden sollen, 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 s-Eigenschaft PageIndex automatisch erhöht.
  4. Binden der entsprechenden Datenseite mithilfe der in Schritt 2 abgerufenen Datensätze an gridView

Das Problem kommt aus der Tatsache, dass in Schritt 2 beim PageIndex Abrufen der anzuzeigenden Datensätze immer noch die PageIndex letzte 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. In Schritt 3 erkennt das GridView dann, dass seine PageIndex Eigenschaft größer als die Gesamtanzahl der Seiten in der Datenquelle ist (seit wir den letzten Datensatz auf der letzten Seite gelöscht haben) und erhöht daher seine PageIndex Eigenschaft. In Schritt 4 versucht die 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. Bei der Standardmäßigen Auslagerung wird dieses Problem nicht angezeigt, 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 nur ein Datensatz vorhanden war, muss der soeben gelöschte Datensatz der letzte sein, und wir müssen die GridView s PageIndexverringern. Natürlich möchten wir nur aktualisieren PageIndex , ob der Löschvorgang tatsächlich erfolgreich war, was bestimmt werden kann, indem sichergestellt wird, dass die e.Exception Eigenschaft ist null.

Dieser Ansatz funktioniert, da er nach PageIndex Schritt 1, aber vor Schritt 2 aktualisiert wird. Daher wird in Schritt 2 der entsprechende Datensatzsatz zurückgegeben. Verwenden Sie dazu Code wie die folgenden:

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 einen Wert von 1 festzulegen. Nach dem Löschen des Datensatzes in Schritt 1 (vor dem erneuten Abrufen der Daten in Schritt 2) aktualisiert das GridView seine PageIndex Eigenschaft, wenn eine oder mehrere Zeilen vom Vorgang betroffen waren. Die AffectedRows Eigenschaft wird jedoch nicht von ObjectDataSource festgelegt, 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 ist. Dies kann mithilfe von Code wie den folgenden erfolgen:

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 dieser Ereignishandler finden Sie in der CodeBehind-Klasse des EfficientPaging.aspx Beispiels.

Vergleich der Leistung von Standard- und benutzerdefinierter Paging

Da das benutzerdefinierte Paging nur die erforderlichen Datensätze abruft, während die Standard paging alle Datensätze für jede angezeigte Seite zurückgibt, ist klar, dass benutzerdefinierte Paging effizienter ist als die Standard paging. Aber wie viel effizienter ist das benutzerdefinierte Paging? Welche Leistungssteigerungen können Sie erkennen, indem Sie von der Standard paging zu benutzerdefinierten Paging wechseln?

Leider passt hier keine Einzige Größe. Der Leistungsgewinn hängt von einer Reihe von Faktoren ab, wobei die anzahl der auf dem Datenbankserver und den Kommunikationskanälen zwischen Webserver und Datenbankserver platzierten Datensätzen am wichtigsten ist. Bei kleinen Tabellen mit nur wenigen Dutzend Datensätzen kann der Leistungsunterschied vernachlässigbar sein. Bei großen Tabellen mit Tausenden bis Hunderten von Zeilen ist der Leistungsunterschied jedoch akut.

Ein Artikel mit "Benutzerdefiniertes Paging in ASP.NET 2.0 mit SQL Server 2005" enthält einige Leistungstests, die ich ausgeführt habe, um die Unterschiede bei der Leistung zwischen diesen beiden Pagingtechniken beim Paging durch eine Datenbanktabelle mit 50.000 Datensätzen zu zeigen. In diesen Tests habe ich sowohl die Zeit zum Ausführen der Abfrage auf SQL Server-Ebene (mit SQL Profiler) als auch auf der ASP.NET Seite mit ASP.NET Ablaufverfolgungsfeatures untersucht. Denken Sie daran, dass diese Tests in meinem Entwicklungsfeld mit einem einzelnen aktiven Benutzer ausgeführt wurden und daher nicht wissenschaftlich sind und keine typischen Websitelademuster nachahmen. Unabhängig davon veranschaulichen die Ergebnisse die relativen Unterschiede bei der Ausführungszeit für standard- und benutzerdefinierte Paging bei der Arbeit mit ausreichend großen Datenmengen.

Durchschn. Dauer (Sek.) Reads
Sql-Standardprofilierer für Paging 1.411 383
Benutzerdefinierter SQL-Profiler für Paging 0.002 29
Standard paging ASP.NET Trace 2.379 N/V
Benutzerdefinierte Paging-ASP.NET-Ablaufverfolgung 0.029 N/V

Wie Sie sehen können, erfordert das Abrufen einer bestimmten Seite mit Daten 354 weniger Lesevorgänge im Durchschnitt und abgeschlossen in einem Bruchteil der Zeit. Auf der ASP.NET Seite konnte die Seite in nahezu 1/100th der Zeit gerendert werden, die beim Verwenden der Standard paging benötigt wurde.

Zusammenfassung

Standardmäßiges Paging ist ein Cinch, um einfach das Kontrollkästchen "Paging aktivieren" im Smarttag des Datenwebsteuerelements zu implementieren, aber diese Einfachheit kommt zu Leistungseinbußen. Wenn ein Benutzer standardmäßig seitenweise Daten anfordert, werden alle Datensätze zurückgegeben, auch wenn nur ein kleiner Bruchteil davon angezeigt werden kann. Um diesen Leistungsaufwand zu bekämpfen, bietet ObjectDataSource eine alternative Pagingoption für benutzerdefinierte Paging-Optionen.

Während das benutzerdefinierte Paging bei Standard-Paging-Leistungsproblemen verbessert wird, indem nur die Datensätze abgerufen werden, die angezeigt werden müssen, ist es wichtiger, benutzerdefinierte 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; Die in diesem Lernprogramm untersuchte Funktion besteht darin, sql Server 2005 s neue ROW_NUMBER() Funktion zum Rangieren von Ergebnissen zu verwenden 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 Gesamtanzahl der Datensätze zu bestimmen, die durchlaufen 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 durchgeblattt werden, und die Werte für den Startzeilenindex und die maximalen Zeilenwerte ordnungsgemäß an die BLL übergeben können.

Die Implementierung von benutzerdefinierten Paging erfordert zwar eine Reihe von Schritten und ist nicht fast so einfach wie die Standard paging, aber benutzerdefiniertes Paging ist eine Notwendigkeit, wenn eine Paging über ausreichend große Datenmengen erfolgt. Wie die untersuchten Ergebnisse gezeigt haben, kann die benutzerdefinierte Seitenverwaltung Sekunden von der ASP.NET Seitenrenderungszeit abschneiden und die Last auf dem Datenbankserver um eine oder mehrere Größenordnungen aufhellen.

Glückliche Programmierung!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft Web Technologies zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann über mitchell@4GuysFromRolla.com seinen Blog erreicht werden, der unter .http://ScottOnWriting.NET