Freigeben über


Löschen in Batches (VB)

von Scott Mitchell

PDF herunterladen

Erfahren Sie, wie Sie mehrere Datenbankeinträge in einem einzigen Vorgang löschen. In der Benutzeroberflächen-Schicht bauen wir auf einer erweiterten GridView auf, die in einem früheren Tutorial erstellt wurde. In der Datenzugriffsebene umschließen wir die mehrere Löschvorgänge innerhalb einer Transaktion, um sicherzustellen, dass alle Löschungen erfolgreich sind oder alle Löschungen rückgängig gemacht werden.

Einleitung

Im vorherigen Lernprogramm wurde erläutert, wie Sie eine Batchbearbeitungsschnittstelle mithilfe einer vollständig bearbeitbaren GridView erstellen. In Situationen, in denen Benutzer häufig viele Datensätze gleichzeitig bearbeiten, erfordert eine Batchbearbeitungsschnittstelle wesentlich weniger Postbacks und Tastatur-zu-Maus-Kontextschalter, wodurch die Effizienz des Endbenutzers verbessert wird. Diese Technik ist ähnlich nützlich für Seiten, auf denen es für Benutzer üblich ist, viele Datensätze einzeln zu löschen.

Jeder, der einen Online-E-Mail-Client verwendet hat, ist bereits mit einer der am häufigsten verwendeten Batchlöschschnittstellen vertraut: ein Kontrollkästchen in jeder Zeile in einem Raster mit einer entsprechenden Schaltfläche "Alle aktivierten Elemente löschen" (siehe Abbildung 1). Dieses Lernprogramm ist eher kurz, da wir bereits alle harte Arbeit in früheren Lernprogrammen beim Erstellen der webbasierten Schnittstelle und einer Methode zum Löschen einer Reihe von Datensätzen als einzelne Atomoperation durchgeführt haben. Im Lernprogramm Hinzufügen einer GridView-Spalte mit Kontrollkästchen haben wir eine GridView mit einer Spalte von Kontrollkästchen erstellt, und im Lernprogramm Datenbankänderungen in einer Transaktion umschließen haben wir eine Methode in der BLL erstellt, die eine Transaktion zum Löschen eines List<T> von ProductID Werten verwendet. In diesem Lernprogramm werden wir auf unseren vorherigen Erfahrungen aufbauen und zusammenführen, um ein beispiel für das Löschen eines funktionierenden Batches zu erstellen.

Jede Zeile enthält ein Kontrollkästchen

Abbildung 1: Jede Zeile enthält ein Kontrollkästchen (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Schritt 1: Erstellen der Batchlöschschnittstelle

Da wir die Batchlöschschnittstelle bereits im Lernprogramm zum Hinzufügen einer GridView-Spalte von Kontrollkästchen erstellt haben, können wir sie einfach kopieren, anstatt sie BatchDelete.aspx von Grund auf neu zu erstellen. Öffnen Sie zunächst die BatchDelete.aspx Seite im BatchData Ordner und die CheckBoxField.aspx Seite im EnhancedGridView Ordner. Wechseln Sie auf der CheckBoxField.aspx Seite zur Quellansicht, und kopieren Sie das Markup zwischen den <asp:Content> Tags, wie in Abbildung 2 dargestellt.

Kopieren des deklarativen Markups von CheckBoxField.aspx in die Zwischenablage

Abbildung 2: Kopieren Sie das deklarative Markup von CheckBoxField.aspx in die Zwischenablage (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Wechseln Sie als Nächstes zur Quellansicht BatchDelete.aspx , und fügen Sie den Inhalt der Zwischenablage innerhalb der <asp:Content> Tags ein. Kopieren und Einfügen Sie den Code auch aus der Code-Behind-Klasse in CheckBoxField.aspx.vb in die Code-Behind-Klasse in BatchDelete.aspx.vb (der DeleteSelectedProducts-Button-Ereignishandler Click, die ToggleCheckState-Methode und die Click-Ereignishandler für die CheckAll- und UncheckAll-Schaltflächen). Nach dem Kopieren dieses Inhalts sollte die Code-Behind-Klasse der BatchDelete.aspx Seite den folgenden Code enthalten:

Partial Class BatchData_BatchDelete
    Inherits System.Web.UI.Page
    Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
        Handles DeleteSelectedProducts.Click
        
        Dim atLeastOneRowDeleted As Boolean = False
        ' Iterate through the Products.Rows property
        For Each row As GridViewRow In Products.Rows
            ' Access the CheckBox
            Dim cb As CheckBox = row.FindControl("ProductSelector")
            If cb IsNot Nothing AndAlso cb.Checked Then
                ' Delete row! (Well, not really...)
                atLeastOneRowDeleted = True
                ' First, get the ProductID for the selected row
                Dim productID As Integer = _
                    Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
                ' "Delete" the row
                DeleteResults.Text &= String.Format _
                    ("This would have deleted ProductID {0}<br />", productID)
                '... To actually delete the product, use ...
                ' Dim productAPI As New ProductsBLL
                ' productAPI.DeleteProduct(productID)
                '............................................
            End If
        Next
        ' Show the Label if at least one row was deleted...
        DeleteResults.Visible = atLeastOneRowDeleted
    End Sub
    Private Sub ToggleCheckState(ByVal checkState As Boolean)
        ' Iterate through the Products.Rows property
        For Each row As GridViewRow In Products.Rows
            ' Access the CheckBox
            Dim cb As CheckBox = row.FindControl("ProductSelector")
            If cb IsNot Nothing Then
                cb.Checked = checkState
            End If
        Next
    End Sub
    Protected Sub CheckAll_Click(sender As Object, e As EventArgs) _
        Handles CheckAll.Click
        ToggleCheckState(True)
    End Sub
    Protected Sub UncheckAll_Click(sender As Object, e As EventArgs) _
        Handles UncheckAll.Click
        ToggleCheckState(False)
    End Sub
End Class

Nachdem Sie das deklarative Markup und den Quellcode kopiert haben, nehmen Sie sich einen Moment Zeit, um es zu testen BatchDelete.aspx , indem Sie es über einen Browser anzeigen. Sie sollten ein GridView sehen, das die ersten zehn Produkte anzeigt, wobei jede Zeile den Namen, die Kategorie und den Preis des Produkts zusammen mit einem Kontrollkästchen auflistet. Es sollten drei Schaltflächen vorhanden sein: "Alle aktivieren", "Alle deaktivieren" und "Ausgewählte Produkte löschen". Beim Klicken auf die Schaltfläche "Alle überprüfen" werden alle Kontrollkästchen aktiviert, während beim Klicken auf "Alle entmarkieren" alle Kontrollkästchen entmarkiert werden. Wenn Sie auf "Ausgewählte Produkte löschen" klicken, wird eine Meldung angezeigt, die die ProductID Werte der ausgewählten Produkte auflistet, die Produkte jedoch nicht tatsächlich löscht.

Die Schnittstelle von CheckBoxField.aspx wurde in BatchDeleting.aspx verschoben.

Abbildung 3: Die Schnittstelle CheckBoxField.aspx wurde verschoben in BatchDeleting.aspx (Klicken, um das Bild in voller Größe anzuzeigen)

Schritt 2: Löschen der überprüften Produkte mithilfe von Transaktionen

Nachdem die Schnittstelle zum Löschen des Batches erfolgreich in die Datei kopiert BatchDeleting.aspxwurde, müssen Sie den Code nur aktualisieren, damit die Schaltfläche "Ausgewählte Produkte löschen" die überprüften Produkte mithilfe der DeleteProductsWithTransaction Methode in der ProductsBLL Klasse löscht. Diese Methode, die im Tutorial Verpacken von Datenbankänderungen innerhalb einer Transaktion hinzugefügt wurde, akzeptiert als Eingabe ein List(Of T) von ProductID Werten und löscht jedes entsprechende ProductID innerhalb des Bereichs der Transaktion.

Der Ereignishandler des DeleteSelectedProducts-Buttons Click verwendet aktuell die folgende For Each-Schleife, um durch jede Zeile des GridView zu iterieren.

' Iterate through the Products.Rows property
For Each row As GridViewRow In Products.Rows
    ' Access the CheckBox
    Dim cb As CheckBox = row.FindControl("ProductSelector")
    If cb IsNot Nothing AndAlso cb.Checked Then
        ' Delete row! (Well, not really...)
        atLeastOneRowDeleted = True
        ' First, get the ProductID for the selected row
        Dim productID As Integer = _
            Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
        ' "Delete" the row
        DeleteResults.Text &= String.Format _
            ("This would have deleted ProductID {0}<br />", productID)
        '... To actually delete the product, use ...
        ' Dim productAPI As New ProductsBLL
        ' productAPI.DeleteProduct(productID)
        '............................................
    End If
Next

Für jede Zeile wird programmgesteuert auf das ProductSelector CheckBox-Websteuerelement verwiesen. Wenn das Kontrollkästchen aktiviert ist, wird die Zeile ProductID aus der DataKeys Sammlung abgerufen und die DeleteResults Label-Eigenschaft Text wird aktualisiert, um eine Nachricht einzuschließen, die angibt, dass die Zeile zum Löschen ausgewählt wurde.

Der obige Code löscht keine Datensätze, da der Aufruf der Methode der ProductsBLL Klasse Delete auskommentiert ist. Wenn diese Löschlogik angewendet würde, würde der Code die Produkte löschen, aber nicht innerhalb einer atomaren Operation. Das heißt, wenn die ersten Löschvorgänge in der Sequenz erfolgreich waren, aber ein späterer Löschversuch (möglicherweise aufgrund einer Verletzung einer Fremdschlüsseleinschränkung) fehlschlägt, wird eine Ausnahme ausgelöst, jedoch bleiben die zuvor gelöschten Produkte gelöscht.

Um die Atomität zu gewährleisten, müssen wir stattdessen die ProductsBLL Klasse und die Methode DeleteProductsWithTransaction verwenden. Da diese Methode eine Liste von ProductID Werten akzeptiert, müssen wir diese Liste zuerst aus dem Raster kompilieren und dann als Parameter übergeben. Wir erstellen zunächst eine Instanz eines List(Of T) von Typ Integer. Innerhalb der For Each-Schleife müssen wir die Werte der ausgewählten Produkte ProductID zu diesem List(Of T) hinzufügen. Nach der Schleife muss dies List(Of T) an die Methode ProductsBLL der Klasse DeleteProductsWithTransaction übergeben werden. Aktualisieren Sie den DeleteSelectedProducts Button-Ereignishandler Click mit dem folgenden Code:

Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
    Handles DeleteSelectedProducts.Click
    
    ' Create a List to hold the ProductID values to delete
    Dim productIDsToDelete As New System.Collections.Generic.List(Of Integer)
    ' Iterate through the Products.Rows property
    For Each row As GridViewRow In Products.Rows
        ' Access the CheckBox
        Dim cb As CheckBox = CType(row.FindControl("ProductSelector"), CheckBox)
        If cb IsNot Nothing AndAlso cb.Checked Then
            ' Save the ProductID value for deletion
            ' First, get the ProductID for the selected row
            Dim productID As Integer = _
                Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
            ' Add it to the List...
            productIDsToDelete.Add(productID)
            ' Add a confirmation message
            DeleteResults.Text &= String.Format _
                ("ProductID {0} has been deleted<br />", productID)
        End If
    Next
    ' Call the DeleteProductsWithTransaction method and show the Label 
    ' if at least one row was deleted...
    If productIDsToDelete.Count > 0 Then
        Dim productAPI As New ProductsBLL()
        productAPI.DeleteProductsWithTransaction(productIDsToDelete)
        DeleteResults.Visible = True
        ' Rebind the data to the GridView
        Products.DataBind()
    End If
End Sub

Der aktualisierte Code erstellt ein List(Of T) vom Typ Integer (productIDsToDelete) und füllt es mit den zu löschenden ProductID Werten auf. Nach der For Each Schleife, wenn mindestens ein Produkt ausgewählt ist, wird die Methode der ProductsBLL Klasse DeleteProductsWithTransaction aufgerufen und die Liste übergeben. Die DeleteResults Beschriftung wird auch angezeigt und die Daten werden an gridView zurückgegeben (sodass die neu gelöschten Datensätze nicht mehr als Zeilen im Raster angezeigt werden).

Abbildung 4 zeigt die GridView, nachdem eine Reihe von Zeilen zum Löschen ausgewählt wurde. Abbildung 5 zeigt den Bildschirm unmittelbar nach dem Klicken auf die Schaltfläche "Ausgewählte Produkte löschen". Beachten Sie, dass in Abbildung 5 die ProductID Werte der gelöschten Datensätze in der Beschriftung unterhalb der GridView angezeigt werden, und diese Zeilen befinden sich nicht mehr in der GridView.

Die ausgewählten Produkte werden gelöscht.

Abbildung 4: Die ausgewählten Produkte werden gelöscht (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Die ProductID-Werte für gelöschte Produkte werden unter der GridView aufgeführt.

Abbildung 5: Die Werte "Gelöschte Produkte ProductID " werden unter "GridView" aufgelistet (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Um die Atomität der DeleteProductsWithTransaction Methode zu testen, fügen Sie manuell einen Eintrag für ein Produkt in der Order Details Tabelle hinzu, und versuchen Sie dann, dieses Produkt (zusammen mit anderen) zu löschen. Beim Versuch, das Produkt mit einer zugeordneten Bestellung zu löschen, erhalten Sie eine Verletzung der Fremdschlüsseleinschränkung. Beachten Sie jedoch, dass die Löschvorgänge der anderen ausgewählten Produkte rückgängig gemacht werden.

Zusammenfassung

Das Erstellen einer Schnittstelle zum Batchlöschen umfasst das Hinzufügen eines GridView-Steuerelements mit einer Spalte von Kontrollkästchen und einem Button-Websteuerelement, das beim Klicken alle markierten Zeilen als eine atomare Operation löscht. In diesem Tutorial haben wir eine solche Schnittstelle erstellt, indem wir Arbeit aus zwei früheren Tutorials zusammengefügt haben: Hinzufügen einer GridView-Spalte von Kontrollkästchen und Verpacken von Datenbankänderungen in einer Transaktion. Im ersten Lernprogramm haben wir ein GridView-Objekt mit einer Spalte von Kontrollkästchen erstellt, und im zweiten haben wir eine Methode in der BLL implementiert, die bei Übergeben einer Sammlung von List(Of T) von ProductID-Werten diese alle im Rahmen einer Transaktion gelöscht hat.

Im nächsten Lernprogramm erstellen wir eine Schnittstelle zum Ausführen von Batcheinfügungen.

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 bei mitchell@4GuysFromRolla.comerreicht werden.

Besonderer Dank an

Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Hilton Giesenow und Teresa Murphy. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn ja, schicken Sie mir eine Nachricht an mitchell@4GuysFromRolla.com.