Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Scott Mitchell
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.
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.
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.
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.aspx
wurde, 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.
Abbildung 4: Die ausgewählten Produkte werden gelöscht (Klicken Sie, um das Bild in voller Größe anzuzeigen)
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.