Share via


Löschen in Batches (VB)

von Scott Mitchell

PDF herunterladen

Erfahren Sie, wie Sie mehrere Datenbankdatensätze in einem einzigen Vorgang löschen. In der Benutzeroberfläche bauen wir auf einer erweiterten GridView auf, die in einem früheren Tutorial erstellt wurde. In der Datenzugriffsebene umschließen wir die mehreren Löschvorgänge innerhalb einer Transaktion, um sicherzustellen, dass alle Löschungen erfolgreich oder alle Löschungen zurückgesetzt werden.

Einführung

Im vorherigen Tutorial wurde das Erstellen einer Batchbearbeitungsschnittstelle mithilfe einer vollständig bearbeitbaren GridView untersucht. In Situationen, in denen Benutzer häufig viele Datensätze gleichzeitig bearbeiten, erfordert eine Batchbearbeitungsschnittstelle viel weniger Postbacks und Kontextwechsel zwischen Tastatur und Maus, wodurch die Effizienz des Endbenutzers verbessert wird. Dieses Verfahren ist ähnlich nützlich für Seiten, auf denen Benutzer häufig viele Datensätze auf einmal löschen.

Jeder, der einen Online-E-Mail-Client verwendet hat, ist bereits mit einer der gängigsten Batchlöschschnittstellen vertraut: ein Kontrollkästchen in jeder Zeile in einem Raster mit einer entsprechenden Schaltfläche Alle überprüften Elemente löschen (siehe Abbildung 1). Dieses Tutorial ist eher kurz, da wir bereits die harte Arbeit in den vorherigen Tutorials beim Erstellen der webbasierten Schnittstelle und einer Methode zum Löschen einer Reihe von Datensätzen als einzelnen atomaren Vorgang ausgeführt haben. Im Tutorial Hinzufügen einer GridView-Spalte von Kontrollkästchen haben wir eine GridView mit einer Spalte von Kontrollkästchen erstellt, und im Tutorial Wrapping Database Modifications in a Transaction haben wir eine Methode in der BLL erstellt, die eine Transaktion zum Löschen von ProductID Werten List<T> verwendet. In diesem Tutorial bauen wir auf unseren vorherigen Erfahrungen auf und führen sie zusammen, um ein Beispiel zum Löschen eines funktionierenden Batchs zu erstellen.

Jede Zeile enthält ein Kontrollkästchen

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

Schritt 1: Erstellen der Batchlöschschnittstelle

Da wir die Batchlöschschnittstelle bereits im Tutorial Hinzufügen einer GridView-Spalte von Kontrollkästchen erstellt haben , können wir sie einfach kopieren, BatchDelete.aspx anstatt sie 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 gezeigt.

Kopieren des deklarativen Markups von CheckBoxField.aspx in die Zwischenablage

Abbildung 2: Kopieren des deklarativen Markups 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 in die <asp:Content> Tags ein. Kopieren Sie außerdem den Code aus der CodeBehind-Klasse inCheckBoxField.aspx.vb, und fügen Sie ihn innerhalb der CodeBehind-Klasse in BatchDelete.aspx.vb ein (den DeleteSelectedProducts Ereignishandler des Button-CodesClick, die ToggleCheckState -Methode und die Click Ereignishandler für die Schaltflächen und UncheckAll ).CheckAll Nach dem Kopieren dieses Inhalts sollte die BatchDelete.aspx CodeBehind-Klasse der 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

Nehmen Sie sich nach dem Kopieren des deklarativen Markups und des Quellcodes einen Moment Zeit, um es zu testen BatchDelete.aspx , indem Sie es über einen Browser anzeigen. Es sollte eine GridView-Liste der ersten zehn Produkte in einer GridView angezeigt werden, wobei jede Zeile den Namen, die Kategorie und den Preis des Produkts sowie ein Kontrollkästchen enthält. Es sollten drei Schaltflächen vorhanden sein: "Alle überprüfen", "Alle" deaktivieren und "Ausgewählte Produkte löschen". Wenn Sie auf die Schaltfläche Alle überprüfen klicken, werden alle Kontrollkästchen aktiviert, während alle Kontrollkästchen deaktiviert 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 nach BatchDeleting.aspx verschoben

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

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

Nachdem die Batchlöschschnittstelle erfolgreich in BatchDeleting.aspxkopiert wurde, bleibt nur noch der Code zu aktualisieren, sodass 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 Wrapping Database Modifications in a Transaction hinzugefügt wurde, akzeptiert als Eingabe a List(Of T) von ProductID Werten und löscht jede ProductID entsprechende innerhalb des Bereichs einer Transaktion.

Der DeleteSelectedProducts Button-Ereignishandler Click verwendet derzeit die folgende For Each Schleife, um jede GridView-Zeile zu durchlaufen:

' 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 es aktiviert ist, wird die Zeile s ProductID aus der DataKeys Auflistung abgerufen, und die DeleteResults Eigenschaft der Text Bezeichnung wird aktualisiert, um eine Meldung zu enthalten, 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 auskommentiert Delete wird. Wenn diese Löschlogik angewendet werden soll, würde der Code die Produkte löschen, aber nicht innerhalb eines atomaren Vorgangs. Das heißt, wenn die ersten Löschvorgänge in der Sequenz erfolgreich waren, aber ein späterer Fehler aufgetreten ist (möglicherweise aufgrund einer Verletzung der Fremdschlüsseleinschränkung), würde eine Ausnahme ausgelöst, aber die bereits gelöschten Produkte blieben gelöscht.

Um die Atomität zu gewährleisten, müssen wir stattdessen die Methode s DeleteProductsWithTransaction der ProductsBLL Klasse verwenden. Da diese Methode eine Liste von ProductID Werten akzeptiert, müssen wir diese Liste zuerst aus dem Raster kompilieren und sie dann als Parameter übergeben. Zuerst erstellen wir eine instance vom List(Of T) Typ Integer. Innerhalb der For Each Schleife müssen wir diesem List(Of T)die ausgewählten Produktwerte ProductID hinzufügen. Nach der Schleife muss diese List(Of T) an die Methode der ProductsBLL Klasse s 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 einen List(Of T) vom Typ Integer (productIDsToDelete) und füllt es mit den ProductID zu löschenden Werten auf. Wenn nach der For Each Schleife mindestens ein Produkt ausgewählt ist, wird die Methode der ProductsBLL Klasse s DeleteProductsWithTransaction aufgerufen und diese Liste übergeben. Außerdem DeleteResults wird die Bezeichnung angezeigt, und die Daten werden an die 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 Bezeichnung unterhalb der GridView angezeigt werden und sich diese Zeilen nicht mehr in der GridView befinden.

Die ausgewählten Produkte werden gelöscht.

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

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

Abbildung 5: Die Werte für gelöschte Produkte ProductID werden unter der Rasteransicht aufgeführt (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. Sie erhalten eine Verletzung der Fremdschlüsseleinschränkung, wenn Sie versuchen, das Produkt mit einer zugeordneten Bestellung zu löschen. Beachten Sie jedoch, wie die löschungen der anderen ausgewählten Produkte zurückgesetzt werden.

Zusammenfassung

Beim Erstellen einer Batchlöschschnittstelle wird eine GridView mit einer Spalte mit Kontrollkästchen und ein Button-Websteuerelement hinzugefügt, das beim Klicken alle ausgewählten Zeilen als einzelnen atomaren Vorgang löscht. In diesem Tutorial haben wir eine solche Schnittstelle erstellt, indem wir die Arbeit in zwei vorherigen Tutorials zusammenarbeiten: Hinzufügen einer GridView-Spalte mit Kontrollkästchen und Umschließen von Datenbankänderungen innerhalb einer Transaktion. Im ersten Tutorial haben wir eine GridView mit einer Spalte von Kontrollkästchen erstellt, und in letzterem haben wir eine Methode in der BLL implementiert, die, wenn ein List(Of T) von ProductID Werten übergeben wurde, alle innerhalb des Bereichs einer Transaktion gelöscht hat.

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

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 Stunden. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderen Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Gutachter für dieses Tutorial waren Hilton Giesenow und Teresa Murphy. Möchten Sie meine anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.