Udostępnij za pośrednictwem


Usuwanie w partiach (VB)

Autor : Scott Mitchell

Pobierz plik PDF

Dowiedz się, jak usunąć wiele rekordów bazy danych w ramach jednej operacji. W warstwie interfejsu użytkownika opieramy się na rozszerzonym elemedycie GridView utworzonym we wcześniejszym samouczku. W warstwie dostępu do danych opakowujemy wiele operacji usuwania w ramach transakcji, aby upewnić się, że wszystkie operacje usuwania powiodły się lub wszystkie usunięcia zostały wycofane.

Wprowadzenie

W poprzednim samouczku przedstawiono sposób tworzenia interfejsu edycji wsadowej przy użyciu w pełni edytowalnego obiektu GridView. W sytuacjach, w których użytkownicy często edytują wiele rekordów jednocześnie, interfejs edycji wsadowej będzie wymagał znacznie mniejszej liczby ogłaszań zwrotnych i przełączników kontekstowych z użyciem klawiatury do myszy, co zwiększa wydajność użytkownika końcowego. Ta technika jest podobnie przydatna w przypadku stron, na których użytkownicy często usuwają wiele rekordów w jednym miejscu.

Każdy, kto używał klienta poczty e-mail online, zna już jeden z najbardziej typowych interfejsów usuwania partii: pole wyboru w każdym wierszu w siatce z odpowiednim przyciskiem Usuń wszystkie zaznaczone elementy (zobacz Rysunek 1). Ten samouczek jest dość krótki, ponieważ wykonaliśmy już całą ciężką pracę w poprzednich samouczkach podczas tworzenia zarówno interfejsu internetowego, jak i metody usuwania serii rekordów jako pojedynczej operacji niepodzielnej. W samouczku Dodawanie kolumny pola wyboru kontrolki GridView utworzyliśmy obiekt GridView z kolumną pól wyboru i w samouczku Zawijanie modyfikacji bazy danych w ramach transakcji utworzyliśmy metodę w bibliotece BLL, która będzie używać transakcji do usuwania List<T>ProductID wartości. W tym samouczku będziemy opierać się na poprzednich środowiskach i scalić je, aby utworzyć przykład usuwania partii roboczej.

Każdy wiersz zawiera pole wyboru

Rysunek 1. Każdy wiersz zawiera pole wyboru (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 1. Tworzenie interfejsu usuwania partii

Ponieważ w samouczku Dodawanie kolumny pól wyboru wsadowego utworzyliśmy już interfejs usuwania wsadowego, możemy po prostu skopiować go do BatchDelete.aspx , zamiast tworzyć go od podstaw. Zacznij od otwarcia BatchDelete.aspx strony w folderze BatchData i CheckBoxField.aspx na stronie w folderze EnhancedGridView . CheckBoxField.aspx Na stronie przejdź do widoku Źródło i skopiuj znaczniki między tagami<asp:Content>, jak pokazano na rysunku 2.

Skopiuj deklaratywny znacznik CheckBoxField.aspx do Schowka

Rysunek 2. Kopiowanie deklaratywnego CheckBoxField.aspx znaczników do Schowka (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Następnie przejdź do widoku Źródło i BatchDelete.aspx wklej zawartość schowka w tagach <asp:Content> . Skopiuj również i wklej kod z klasy za pomocą kodu w CheckBoxField.aspx.vb klasie do w klasie za kodem w BatchDelete.aspx.vb programie ( DeleteSelectedProducts procedura obsługi zdarzeń przycisku Click , ToggleCheckState metoda i Click programy obsługi zdarzeń dla CheckAll elementów i UncheckAll Buttons). Po skopiowaniu tej zawartości BatchDelete.aspx klasa s code-behind strony powinna zawierać następujący kod:

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

Po skopiowaniu deklaratywnego znaczników i kodu źródłowego poświęć chwilę na przetestowanie BatchDelete.aspx , wyświetlając go za pośrednictwem przeglądarki. Element GridView powinien zawierać listę pierwszych dziesięciu produktów w elementy GridView z każdym wierszem zawierającym nazwę, kategorię i cenę produktu wraz z polem wyboru. Powinny istnieć trzy przyciski: Zaznacz wszystko, Usuń zaznaczenie pola wyboru Wszystkie i Usuń wybrane produkty. Kliknięcie przycisku Zaznacz wszystko zaznacza wszystkie pola wyboru, a zaznaczenie pola wyboru Wszystkie usuwa zaznaczenie wszystkich pól wyboru. Kliknięcie pozycji Usuń wybrane produkty powoduje wyświetlenie komunikatu ProductID z listą wartości wybranych produktów, ale w rzeczywistości nie powoduje usunięcia produktów.

Interfejs z CheckBoxField.aspx został przeniesiony do BatchDeleting.aspx

Rysunek 3. Interfejs z CheckBoxField.aspx został przeniesiony do BatchDeleting.aspx (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Krok 2. Usuwanie sprawdzonych produktów przy użyciu transakcji

Po pomyślnym skopiowaniu interfejsu usuwania wsadowego do BatchDeleting.aspxmetody wystarczy zaktualizować kod, aby przycisk Usuń wybrane produkty usunął zaznaczone produkty przy użyciu DeleteProductsWithTransaction metody w ProductsBLL klasie . Ta metoda, dodana w samouczku Zawijanie modyfikacji bazy danych w ramach transakcji , akceptuje jako dane wejściowe List(Of T)ProductID wartości i usuwa wszystkie odpowiadające ProductID w zakresie transakcji.

Procedura DeleteSelectedProducts obsługi zdarzeń przycisku Click używa obecnie następującej For Each pętli do iterowania po każdym wierszu GridView:

' 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

Dla każdego wiersza kontrolka ProductSelector sieci Web CheckBox jest programowo przywoływana. Jeśli jest zaznaczone, wiersze są ProductID pobierane z DataKeys kolekcji, a DeleteResults właściwość Etykieta Text jest aktualizowana w celu uwzględnienia komunikatu wskazującego, że wiersz został wybrany do usunięcia.

Powyższy kod nie usuwa żadnych rekordów, ponieważ wywołanie ProductsBLL metody klasy jest Delete oznaczane jako komentarz. Gdyby ta logika usuwania została zastosowana, kod usunąłby produkty, ale nie w ramach operacji niepodzielnej. Oznacza to, że jeśli pierwsze kilka operacji usuwania w sekwencji zakończyło się pomyślnie, ale późniejsza nie powiodła się (być może z powodu naruszenia ograniczenia klucza obcego), zostanie zgłoszony wyjątek, ale usunięte produkty pozostaną usunięte.

Aby zapewnić niepodzielność, musimy zamiast tego użyć ProductsBLL metody klasy s DeleteProductsWithTransaction . Ponieważ ta metoda akceptuje listę ProductID wartości, musimy najpierw skompilować tę listę z siatki, a następnie przekazać ją jako parametr. Najpierw tworzymy wystąpienie List(Of T) typu Integer. For Each W pętli musimy dodać wybrane wartości produktów ProductID do tego List(Of T)elementu . Po pętli należy przekazać tę List(Of T) pętlę ProductsBLL do metody klasy s DeleteProductsWithTransaction . Zaktualizuj program obsługi zdarzeń DeleteSelectedProducts przycisku Click przy użyciu następującego kodu:

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

Zaktualizowany kod tworzy List(Of T) typ Integer (productIDsToDelete) i wypełnia go wartościami ProductID do usunięcia. For Each Po pętli, jeśli wybrano co najmniej jeden produkt, ProductsBLL metoda klasy jest wywoływana DeleteProductsWithTransaction i przekazuje tę listę. Etykieta DeleteResults jest również wyświetlana i dane odbicia do kontrolki GridView (tak aby nowo usunięte rekordy nie pojawiały się już jako wiersze w siatce).

Rysunek 4 przedstawia obiekt GridView po wybraniu kilku wierszy do usunięcia. Rysunek 5 przedstawia ekran natychmiast po kliknięciu przycisku Usuń wybrane produkty. Zwróć uwagę, że na rysunku 5 ProductID wartości usuniętych rekordów są wyświetlane w obszarze Etykieta pod kontrolką GridView, a te wiersze nie znajdują się już w siatce.

Wybrane produkty zostaną usunięte

Rysunek 4. Wybrane produkty zostaną usunięte (kliknij, aby wyświetlić obraz pełnowymiarowy)

Wartości ProductID usuniętych produktów są wyświetlane pod kontrolką GridView

Rysunek 5. Wartości usuniętych produktów ProductID są wyświetlane pod kontrolką GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Aby przetestować DeleteProductsWithTransaction niepodzielność metody, ręcznie dodaj wpis dla produktu w Order Details tabeli, a następnie spróbuj usunąć ten produkt (wraz z innymi). Podczas próby usunięcia produktu ze skojarzonym zamówieniem otrzymasz naruszenie ograniczenia klucza obcego, ale zwróć uwagę na sposób wycofywania innych wybranych produktów.

Podsumowanie

Utworzenie interfejsu usuwania wsadowego obejmuje dodanie kontrolki GridView z kolumną pól wyboru i kontrolką Sieci Web przycisku, która po kliknięciu spowoduje usunięcie wszystkich zaznaczonych wierszy jako pojedynczej operacji niepodzielnej. W tym samouczku utworzyliśmy taki interfejs, łącząc pracę wykonaną w dwóch poprzednich samouczkach: Dodawanie kolumny GridView pól wyboru i zawijanie modyfikacji bazy danych w ramach transakcji. W pierwszym samouczku utworzyliśmy obiekt GridView z kolumną pól wyboru, a w drugim zaimplementowaliśmy metodę w bibliotece BLL, która po przekazaniu List(Of T)ProductID wartości usunęła je wszystkie w zakresie transakcji.

W następnym samouczku utworzymy interfejs do wykonywania wstawiania wsadowego.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Hilton Giesenow i Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .