Sdílet prostřednictvím


Dávkové odstraňování (C#)

Scott Mitchell

Stáhnout PDF

Zjistěte, jak odstranit více databázových záznamů v rámci jedné operace. Ve vrstvě uživatelského rozhraní vycházíme z vylepšeného objektu GridView vytvořeného v dřívějším kurzu. Ve vrstvě přístupu k datům zabalíme několik operací odstranění v rámci transakce, abychom zajistili, že všechna odstranění budou úspěšná nebo vrácená zpět.

Úvod

Předchozí kurz zkoumal, jak vytvořit rozhraní pro dávkové úpravy pomocí plně upravitelného objektu GridView. V situacích, kdy uživatelé často upravují mnoho záznamů najednou, bude rozhraní dávkové úpravy vyžadovat mnohem méně zpětných volání a kontextových přepínačů mezi klávesnicí a myší, což zlepší efektivitu koncového uživatele. 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žíval online e-mailového klienta, už zná jedno z nejběžnějších rozhraní dávkového odstraňování: zaškrtávací políčka v každém řádku v mřížce 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 již provedli veškerou tvrdou práci v předchozích kurzech při vytváření webového rozhraní a metody odstranění řady záznamů jako jedné atomické operace. V kurzu Přidání sloupce zaškrtávacích políček GridView jsme vytvořili GridView se sloupcem zaškrtávacích políček a v kurzu Obtékání úprav databáze v rámci transakce jsme vytvořili metodu v BLL, která by použila transakci k odstranění List<T>ProductID hodnoty. V tomto kurzu budeme stavět na našich předchozích prostředích a sloučit je, abychom vytvořili funkční příklad dávkového odstraně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í pro odstraňování dávky

Vzhledem k tomu, že jsme již vytvořili rozhraní dávkového odstraňování v kurzu Přidání sloupce GridView zaškrtávacích políček , můžeme ho jednoduše zkopírovat do BatchDelete.aspx , nikoli vytvořit od začátku. Začněte otevřením BatchDelete.aspx stránky ve BatchData složce a CheckBoxField.aspx stránky ve EnhancedGridView složce. Ze CheckBoxField.aspx stránky přejděte do zobrazení Zdroj a zkopírujte značky mezi <asp:Content> značky, jak je znázorněno na obrázku 2.

Zkopírování deklarativního kódu CheckBoxField.aspx do schránky

Obrázek 2: Zkopírování deklarativního CheckBoxField.aspx kódu do schránky (kliknutím zobrazíte obrázek v plné velikosti)

Pak přejděte do zobrazení Zdroj v BatchDelete.aspx a vložte obsah schránky do značek <asp:Content> . Kód také zkopírujte a vložte z třídy code-behind v CheckBoxField.aspx.cs souboru do třídy kódu na pozadí v BatchDelete.aspx.cs systému ( DeleteSelectedProducts obslužná rutina události Button s Click , ToggleCheckState metoda a Click obslužné rutiny událostí pro CheckAll tlačítka a UncheckAll ). Po zkopírování tohoto obsahu BatchDelete.aspx by třída kódu na pozadí stránky měla obsahovat následující kód:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class BatchData_BatchDelete : System.Web.UI.Page
{
    protected void DeleteSelectedProducts_Click(object sender, EventArgs e)
    {
        bool atLeastOneRowDeleted = false;
        // Iterate through the Products.Rows property
        foreach (GridViewRow row in Products.Rows)
        {
            // Access the CheckBox
            CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
            if (cb != null && cb.Checked)
            {
                // Delete row! (Well, not really...)
                atLeastOneRowDeleted = true;
                // First, get the ProductID for the selected row
                int productID = 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 ...
                //ProductsBLL productAPI = new ProductsBLL();
                //productAPI.DeleteProduct(productID);
                //............................................
            }
        }
        // Show the Label if at least one row was deleted...
        DeleteResults.Visible = atLeastOneRowDeleted;
    }
    private void ToggleCheckState(bool checkState)
    {
        // Iterate through the Products.Rows property
        foreach (GridViewRow row in Products.Rows)
        {
            // Access the CheckBox
            CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
            if (cb != null)
                cb.Checked = checkState;
        }
    }
    protected void CheckAll_Click(object sender, EventArgs e)
    {
        ToggleCheckState(true);
    }
    protected void UncheckAll_Click(object sender, EventArgs e)
    {
        ToggleCheckState(false);
    }
}

Po zkopírování deklarativního kódu a zdrojového kódu chvíli vyzkoušejte BatchDelete.aspx zobrazením v prohlížeči. Měli byste vidět GridView se seznamem prvních deseti produktů v GridView s každým řádkem se seznamem názvu produktu, kategorie a ceny 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 zaškrtnutí všech políček zrušíte. 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 v plné velikosti)

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

Po úspěšném zkopírování rozhraní pro odstranění dávky do BatchDeleting.aspxnástroje zbývá pouze aktualizovat kód tak, aby tlačítko Odstranit vybrané produkty odstranilo kontrolované produkty pomocí DeleteProductsWithTransaction metody ve ProductsBLL třídě . Tato metoda, přidaná v kurzu Obtékání úprav databáze v rámci transakce , přijímá jako vstup List<T>ProductID hodnoty a odstraní každou odpovídající ProductID v rámci rozsahu transakce.

Obslužná rutina DeleteSelectedProducts události Button s Click aktuálně používá následující foreach smyčku k iteraci jednotlivými řádky GridView:

// Iterate through the Products.Rows property
foreach (GridViewRow row in Products.Rows)
{
    // Access the CheckBox
    CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
    if (cb != null && cb.Checked)
    {
        // Delete row! (Well, not really...)
        atLeastOneRowDeleted = true;
        // First, get the ProductID for the selected row
        int productID = 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 ...
        //ProductsBLL productAPI = new ProductsBLL();
        //productAPI.DeleteProduct(productID);
        //............................................
    }
}

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

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

Abychom zajistili nedělitelnost, musíme místo toho použít metodu ProductsBLL třídy s DeleteProductsWithTransaction . Vzhledem k tomu, že tato metoda přijímá seznam ProductID hodnot, musíme tento seznam nejprve zkompilovat z mřížky a pak ho předat jako parametr. Nejprve vytvoříme instanci List<T> typu int. V rámci smyčky foreach musíme k tomuto List<T>objektu přidat hodnoty vybraných produktůProductID. Po smyčce se musí List<T> předat ProductsBLL metodě třídy s DeleteProductsWithTransaction . Aktualizujte obslužnou rutinu DeleteSelectedProducts události Button s Click následujícím kódem:

protected void DeleteSelectedProducts_Click(object sender, EventArgs e)
{
    // Create a List to hold the ProductID values to delete
    System.Collections.Generic.List<int> productIDsToDelete = 
        new System.Collections.Generic.List<int>();
    // Iterate through the Products.Rows property
    foreach (GridViewRow row in Products.Rows)
    {
        // Access the CheckBox
        CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
        if (cb != null && cb.Checked)
        {
            // Save the ProductID value for deletion
            // First, get the ProductID for the selected row
            int productID = 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);
        }
    }
    // Call the DeleteProductsWithTransaction method and show the Label 
    // if at least one row was deleted...
    if (productIDsToDelete.Count > 0)
    {
        ProductsBLL productAPI = new ProductsBLL();
        productAPI.DeleteProductsWithTransaction(productIDsToDelete);
        DeleteResults.Visible = true;
        // Rebind the data to the GridView
        Products.DataBind();
    }
}

Aktualizovaný kód vytvoří List<T> typ int (productIDsToDelete) a naplní ho hodnotami, ProductID které se mají odstranit. Po smyčce foreach , pokud je vybrán alespoň jeden produkt, ProductsBLL je volána metoda třídy s DeleteProductsWithTransaction a předána tento seznam. Zobrazí DeleteResults se také popisek a data se přeskočí do objektu GridView (aby se nově odstraněné záznamy už nezobrazovaly jako řádky v mřížce).

Obrázek 4 znázorňuje GridView po výběru počtu řádků k odstranění. Obrázek 5 znázorňuje obrazovku hned po kliknutí na tlačítko Odstranit vybrané produkty. Všimněte si, že na obrázku ProductID 5 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 v plné velikosti)

Hodnoty Idproduktu odstraněných produktů jsou uvedené pod objektem GridView.

Obrázek 5: Hodnoty Odstraněné produkty ProductID jsou uvedené pod objektem GridView (kliknutím zobrazíte obrázek v plné velikosti).

Poznámka

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

Souhrn

Vytvoření rozhraní dávkového odstraňová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 jednu atomické operace. 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 zaškrtávacích políček 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 ve druhém jsme implementovali metodu v BLL, která při předání List<T>ProductID hodnoty odstranila všechny v rámci rozsahu transakce.

V dalším kurzu vytvoříme rozhraní pro dávkové vkládání.

Všechno nejlepší na programování!

O autorovi

Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.

Zvláštní poděkování

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byly Hilton Giesenow a Teresa Murphy. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.