Sdílet prostřednictvím


Hromadné odstraňování (VB)

od Scott Mitchell

Stáhnout PDF

Zjistěte, jak odstranit více záznamů databáze v jedné operaci. Ve vrstvě uživatelského rozhraní stavíme na vylepšeném objektu GridView vytvořeném v předchozím kurzu. Ve vrstvě přístupu k datům zabalíme více operací odstranění v rámci transakce, aby se zajistilo, že všechna odstranění proběhnou úspěšně nebo všechny odstranění se vrátí zpět.

Úvod

Předchozí kurz prozkoumal, jak vytvořit dávkové rozhraní pro úpravy pomocí plně upravitelného objektu GridView. V situacích, kdy uživatelé často upravují mnoho záznamů najednou, bude dávkové rozhraní pro úpravy vyžadovat mnohem méně postbacků a přepínačů kontextu myši, čímž zlepšuje efektivitu koncových uživatelů. Tato technika je podobně užitečná pro stránky, kde je běžné, že uživatelé odstraní mnoho záznamů najednou.

Každý, kdo použil online e-mailový klient, je již obeznámený s jedním z nejběžnějších rozhraní pro hromadné mazání: zaškrtávací políčko v každém řádku tabulky s odpovídajícím tlačítkem Odstranit všechny zaškrtnuté položky (viz obrázek 1). Tento kurz je poměrně krátký, protože jsme už provedli veškerou tvrdou práci v předchozích kurzech při vytváření webového rozhraní i metody pro odstranění řady záznamů jako jedné atomické operace. V Přidání sloupce zaškrtávacích políček do GridView jsme vytvořili GridView se sloupcem zaškrtávacích políček a v Obalení úprav databáze v rámci transakce kurzu jsme vytvořili metodu v BLL, která by použila transakci k odstranění List<T> hodnot ProductID. V tomto kurzu na základě našich předchozích zkušeností vytvoříme a spojíme je do fungujícího příkladu hromadného mazání.

Každý řádek obsahuje zaškrtávací políčko

Obrázek 1: Každý řádek obsahuje zaškrtávací políčko (kliknutím zobrazíte obrázek v plné velikosti)

Krok 1: Vytvoření rozhraní dávkového odstraňování

Vzhledem k tomu, že jsme už vytvořili rozhraní pro dávkové mazání v kurzu Přidání sloupce GridView zaškrtávacích políček, můžeme ho jednoduše zkopírovat do BatchDelete.aspx, místo abychom ho vytvářeli úplně od začátku. Začněte otevřením stránky BatchDelete.aspx ve složce BatchData a stránky CheckBoxField.aspx ve složce EnhancedGridView. Na stránce CheckBoxField.aspx, přejděte do zobrazení zdrojového kódu a zkopírujte značky mezi tagy <asp:Content>, jak je znázorněno na obrázku 2.

Zkopírujte deklarativní kód CheckBoxField.aspx do schránky.

Obrázek 2: Zkopírujte deklarativní značkování CheckBoxField.aspx do schránky (Kliknutím zobrazíte obrázek v plné velikosti)

Dále přejděte do zobrazení zdroje v BatchDelete.aspx a vložte obsah schránky dovnitř značek <asp:Content>. Také zkopírujte a vložte kód z kódové třídy na pozadí ve CheckBoxField.aspx.vb do kódové třídy na pozadí ve BatchDelete.aspx.vb (obslužná rutina události pro tlačítko DeleteSelectedProducts s Click, metoda ToggleCheckState a obslužné rutiny událostí pro tlačítka Click a CheckAll). Po přesunutí tohoto obsahu by třída pro kód na pozadí stránky BatchDelete.aspx měla obsahovat následující kód:

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 zkopírování deklarativního kódu a zdrojového kódu chvilku otestujte BatchDelete.aspx zobrazením v prohlížeči. Měli byste vidět GridView, který zobrazuje seznam prvních deseti produktů, kde každý řádek obsahuje název produktu, kategorii a cenu spolu se zaškrtávacím políčkem. Měla by existovat tři tlačítka: Zaškrtnout vše, Zrušit zaškrtnutí všech a Odstranit vybrané produkty. Kliknutím na tlačítko Zaškrtnout vše zaškrtnete všechna políčka, zatímco tlačítko Odškrtnout vše zruší všechna zaškrtnutí. Kliknutím na odstranit vybrané produkty se zobrazí zpráva se seznamem ProductID hodnot vybraných produktů, ale produkty se ve skutečnosti neodstraní.

Rozhraní z CheckBoxField.aspx bylo přesunuto do BatchDeleting.aspx

Obrázek 3: Rozhraní z CheckBoxField.aspx bylo přesunuto do BatchDeleting.aspx (Kliknutím zobrazíte obrázek s plnou velikostí)

Krok 2: Odstranění kontrolovaných produktů pomocí transakcí

Po úspěšném zkopírování rozhraní dávkového odstraňování do BatchDeleting.aspx zbývá pouze aktualizovat kód tak, aby tlačítko Odstranit vybrané produkty odstranilo označené produkty pomocí metody DeleteProductsWithTransaction ve třídě ProductsBLL. Tato metoda, přidána v tutoriálu Zabalení úprav databáze v rámci transakce, přijímá jako vstup hodnoty List(Of T)ProductID a odstraní každý odpovídající ProductID v rozsahu transakce.

Obslužná rutina události DeleteSelectedProducts tlačítka Click v současné době používá následující For Each cyklus k procházení každým řádkem 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

U každého řádku ProductSelector se na ovládací prvek CheckBox Web odkazuje programově. Pokud je zaškrtnuté, řádek s ProductID se načte z DataKeys kolekce a DeleteResults vlastnost Popisek Text se aktualizuje tak, aby obsahovala zprávu označující, že byl řádek vybrán k odstranění.

Výše uvedený kód ve skutečnosti neodstraní žádné záznamy, protože volání metody třídy ProductsBLL s Delete je okomentováno. Pokud by byla použita tato logika mazání, kód by odstranil produkty, ale ne v rámci atomární operace. To znamená, že pokud se první několik odstranění v sekvenci úspěšně odstranilo, ale později došlo k selhání (možná kvůli porušení omezení cizího klíče), vyvolá se výjimka, ale produkty, které už byly odstraněny, zůstanou odstraněny.

Abychom zajistili atomicitu, musíme místo toho použít metodu ProductsBLL třídy s DeleteProductsWithTransaction . Protože tato metoda přijímá seznam ProductID hodnot, musíme nejprve zkompilovat tento seznam z mřížky a pak ho předat jako parametr. Nejprve vytvoříme instanci List(Of T) typu Integer. Ve smyčce musíme přidat hodnoty vybraných produktů For Each k této položce ProductID. Po smyčce musí být List(Of T) předáno metodě ProductsBLL třídy DeleteProductsWithTransaction. Aktualizujte obslužnou rutinu události DeleteSelectedProducts s tlačítkem Click pomocí následujícího kódu:

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

Aktualizovaný kód vytvoří List(Of T) typu Integer (productIDsToDelete) a naplní ho hodnotami ProductID, které mají být odstraněny. Po smyčce For Each, pokud je vybrán alespoň jeden produkt, je zavolána metoda ProductsBLL třídy DeleteProductsWithTransaction a je jí předán tento seznam. Popisek DeleteResults se také zobrazí a data se přepojují do objektu GridView (aby se nově odstraněné záznamy už nezobrazovaly jako řádky v tabulce).

Obrázek 4 znázorňuje GridView po výběru řady řádků k odstranění. Obrázek 5 ukazuje obrazovku hned po kliknutí na tlačítko Odstranit vybrané produkty. Všimněte si, že na obrázku 5 ProductID se hodnoty odstraněných záznamů zobrazují v popisku pod objektem GridView a tyto řádky už nejsou v objektu GridView.

Vybrané produkty budou odstraněny.

Obrázek 4: Vybrané produkty budou odstraněny (kliknutím zobrazíte obrázek s plnou velikostí)

Hodnoty PRODUCTID odstraněných produktů jsou uvedeny pod objektem GridView.

Obrázek 5: Hodnoty odstraněných produktů ProductID jsou uvedeny pod objektem GridView (kliknutím zobrazíte obrázek s plnou velikostí).

Poznámka:

Pokud chcete otestovat DeleteProductsWithTransaction atomičnost metody, přidejte ručně položku pro produkt v Order Details tabulce a pak se pokuste tento produkt odstranit (společně s ostatními). Při pokusu o odstranění produktu, který má přidruženou objednávku, obdržíte porušení omezení cizího klíče. Všimněte si však, jak se odstranění dalších vybraných produktů vrátí zpět.

Shrnutí

Vytvoření rozhraní pro dávkové mazání zahrnuje přidání GridView se sloupcem zaškrtávacích políček a webového ovládacího prvku Button, který po kliknutí odstraní všechny vybrané řádky jako operaci jednoho atomu. V tomto kurzu jsme vytvořili takové rozhraní tak, že jsme společně vytvořili práci provedenou ve dvou předchozích kurzech, přidání sloupce GridView se zaškrtávacími políčky a zabalení úprav databáze v rámci transakce. V prvním kurzu jsme vytvořili GridView se sloupcem zaškrtávacích políček a v druhém jsme implementovali metodu v BLL, která při předání List(Of T)ProductID hodnot odstranila všechny v rámci oboru transakce.

V dalším kurzu vytvoříme rozhraní pro provádění dávkových vkládání.

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Naučte se ASP.NET 2,0 za 24 hodin. Může být dosažitelný na mitchell@4GuysFromRolla.comadrese .

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí hodnotící pro tento kurz byli Hilton Giesenow a Teresa Murphy. Chcete si projít nadcházející články MSDN? Pokud ano, napište mi zprávu na mitchell@4GuysFromRolla.com.