Sdílet prostřednictvím


Dávkové aktualizace (VB)

Scott Mitchell

Stáhnout PDF

Zjistěte, jak aktualizovat více záznamů databáze v jedné operaci. Ve vrstvě uživatelského rozhraní vytvoříme GridView, kde je každý řádek upravitelný. Ve vrstvě přístupu k datům zabalíme více operací aktualizace v rámci transakce, aby se zajistilo, že všechny aktualizace budou úspěšné nebo všechny aktualizace se vrátí zpět.

Úvod

V předchozím kurzu jsme zjistili, jak rozšířit vrstvu přístupu k datům o přidání podpory databázových transakcí. Databázové transakce zaručují, že řada příkazů pro úpravu dat bude považována za jednu atomické operace, která zajistí, že všechny úpravy selžou nebo všechny budou úspěšné. Díky této funkci DAL nízké úrovně jsme připraveni zaměřit se na vytváření rozhraní pro úpravy dávkových dat.

V tomto kurzu vytvoříme GridView, kde je každý řádek upravitelný (viz obrázek 1). Vzhledem k tomu, že se každý řádek vykresluje v rozhraní pro úpravy, není nutné používat sloupce tlačítek Upravit, Aktualizovat a Zrušit. Místo toho jsou na stránce dvě tlačítka Update Products, která po kliknutí vyčíslí řádky GridView a aktualizují databázi.

Každý řádek v objektu GridView je upravitelný.

Obrázek 1: Každý řádek v objektu GridView je upravitelný (kliknutím zobrazíte obrázek s plnou velikostí)

Pojďme začít!

Poznámka:

V kurzu Provádění dávkových aktualizací jsme vytvořili rozhraní dávkové úpravy pomocí ovládacího prvku DataList. Tento kurz se liší od předchozího v tom, že používá GridView a dávková aktualizace se provádí v rámci oboru transakce. Po dokončení tohoto kurzu doporučuji, abyste se vrátili do předchozího kurzu a aktualizovali ji tak, aby používala funkce související s transakcemi databáze přidané v předchozím kurzu.

Prozkoumání kroků pro úpravu všech řádků GridView

Jak je popsáno v kurzu Vložení, aktualizace a odstranění dat , gridView nabízí integrovanou podporu pro úpravy podkladových dat na jednotlivé řádky. GridView interně zaznamená, jaký řádek je možné upravovat prostřednictvím jeho EditIndex vlastnosti. Vzhledem k tomu, že Objekt GridView je svázán s jeho zdrojem dat, kontroluje každý řádek, aby zjistil, jestli se index řádku rovná hodnotě EditIndex. Pokud ano, pole řádků se vykreslují pomocí jejich rozhraní pro úpravy. Pro BoundFields je rozhraní pro úpravy TextBox, jehož Text vlastnost je přiřazena hodnota datového pole určeného BoundField vlastnost DataField . Pro TemplateFields se EditItemTemplate používá místo ItemTemplate.

Vzpomeňte si, že pracovní postup úprav začíná, když uživatel klikne na tlačítko Upravit řádek. To způsobí postback, nastaví GridView s EditIndex vlastnost na index klikaného řádku a znovubindí data do mřížky. Po kliknutí na tlačítko Storno řádku je při zpětném EditIndex vrácení nastavena hodnota -1 před opětovnou vazbou dat do mřížky. Vzhledem k tomu, že řádky GridView s začínají indexovat na nulu, EditIndex -1 nastavení má vliv na zobrazení GridView v režimu jen pro čtení.

Vlastnost EditIndex funguje dobře pro úpravy jednotlivých řádků, ale není určená pro dávkové úpravy. Abychom mohli upravit celý Objekt GridView, musíme mít každý řádek vykreslený pomocí jeho rozhraní pro úpravy. Nejjednodušším způsobem, jak toho dosáhnout, je vytvořit, kde se každé upravitelné pole implementuje jako TemplateField s jeho rozhraním pro úpravy definované v ItemTemplaterozhraní .

V dalších několika krocích vytvoříme zcela upravitelný Objekt GridView. V kroku 1 začneme vytvořením objektu GridView a jeho ObjectDataSource a převodem jeho BoundField a CheckBoxField na TemplateFields. V krocích 2 a 3 přesuneme rozhraní pro úpravy z TemplateFields EditItemTemplate na jejich ItemTemplate rozhraní.

Krok 1: Zobrazení informací o produktu

Než se budeme starat o vytvoření objektu GridView, kde jsou řádky upravitelné, začněme jednoduchým zobrazením informací o produktu. BatchUpdate.aspx Otevřete stránku ve BatchData složce a přetáhněte Objekt GridView ze sady nástrojů do Návrháře. Nastavte Objekt GridView na ID ProductsGrid a z jeho inteligentní značky zvolte, že se má svázat s novým ObjectDataSource s názvem ProductsDataSource. Nakonfigurujte ObjectDataSource pro načtení dat z ProductsBLL metody třídy s GetProducts .

Konfigurace ObjectDataSource pro použití třídy ProductsBLL

Obrázek 2: Konfigurace ObjectDataSource pro použití ProductsBLL třídy (kliknutím zobrazíte obrázek v plné velikosti)

Načtení dat produktu pomocí metody GetProducts

Obrázek 3: Načtení dat o produktu pomocí GetProducts metody (kliknutím zobrazíte obrázek s plnou velikostí)

Podobně jako GridView jsou funkce úprav ObjectDataSource navržené tak, aby fungovaly na jednotlivých řádech. Abychom mohli aktualizovat sadu záznamů, budeme muset napsat část kódu na ASP.NET stránce s kódem za třídou, která dávková data a předává je do knihovny BLL. Proto nastavte rozevírací seznamy na kartě ObjectDataSource s UPDATE, INSERT a DELETE na (Žádné). Dokončete průvodce kliknutím na Dokončit.

Nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné).

Obrázek 4: Nastavení rozevíracích seznamů na kartách UPDATE, INSERT a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce konfigurací zdroje dat by deklarativní kód ObjectDataSource měl vypadat takto:

<asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

Dokončení průvodce konfigurací zdroje dat také způsobí, že Visual Studio vytvoří BoundFields a CheckBoxField pro pole dat produktu v GridView. V tomto kurzu umožníme uživateli jenom zobrazit a upravit název produktu, kategorii, cenu a ukončený stav. Odeberte všechna pole , ale ProductName, CategoryNamea pole a Discontinued přejmenujte HeaderText vlastnosti prvních tří polí na Product( Kategorie) a UnitPricePrice (Cena). Nakonec zaškrtněte políčka Povolit stránkování a Povolit řazení v inteligentní značce GridView.

V tomto okamžiku má GridView tři BoundFields (ProductName, CategoryNamea UnitPrice) a CheckBoxField (Discontinued). Potřebujeme převést tato čtyři pole na TemplateFields a pak přesunout rozhraní pro úpravy z TemplateField s EditItemTemplate do jeho ItemTemplate.

Poznámka:

V kurzu Přizpůsobení rozhraní pro úpravu dat jsme prozkoumali vytváření a přizpůsobení polí TemplateFields. Projdeme si kroky převodu BoundFields a CheckBoxField na TemplateFields a definování jejich rozhraní pro úpravy v jejich ItemTemplate s, ale pokud se zaseknete nebo potřebujete aktualizační modul, neváhejte se vrátit k tomuto dřívějšímu kurzu.

Z inteligentní značky GridView klikněte na odkaz Upravit sloupce a otevřete dialogové okno Pole. Dále vyberte jednotlivá pole a klikněte na tlačítko Převést toto pole na odkaz TemplateField.

Převod existujících boundfields a CheckBoxField na TemplateFields

Obrázek 5: Převod existujících polí BoundField a CheckBoxField na templateFields

Teď, když je každé pole TemplateField, jsme připraveni přesunout rozhraní pro úpravy z objektu EditItemTemplate s na ItemTemplate s.

Krok 2: VytvořeníProductNameUnitPrice rozhraní aDiscontinuedúpravy

ProductNameVytvoření rozhraní , UnitPricea Discontinued úpravy rozhraní jsou téma tohoto kroku a jsou poměrně jednoduché, protože každé rozhraní je již definováno v TemplateField s EditItemTemplate. CategoryName Vytvoření rozhraní pro úpravy je trochu více zapojeno, protože potřebujeme vytvořit Rozevírací seznam použitelných kategorií. Toto CategoryName rozhraní pro úpravy je řešeno v kroku 3.

Začněme polem ProductName TemplateField. Klikněte na odkaz Upravit šablony z inteligentní značky GridView s a přejděte k podrobnostem ProductName na TemplateField s EditItemTemplate. Vyberte Textové pole, zkopírujte ho do schránky a vložte ho ProductName do TemplateField s ItemTemplate. Změňte vlastnost TextBox ID na ProductName.

Dále přidejte RequiredFieldValidator, ItemTemplate aby se zajistilo, že uživatel poskytne hodnotu pro každý název produktu. ControlToValidate Nastavte vlastnost Na ProductName, ErrorMessage vlastnost na Hodnotu Je nutné zadat název produktu. Text a vlastnost *. Po přidání těchto doplňků na obrazovku ItemTemplateby měla obrazovka vypadat podobně jako na obrázku 6.

Pole TemplateField ProductName teď obsahuje TextBox a RequiredFieldValidator.

Obrázek 6: Pole ProductName šablony teď obsahuje Textové pole a RequiredFieldValidator (kliknutím zobrazíte obrázek v plné velikosti).

UnitPrice Pro rozhraní pro úpravy začněte zkopírováním textového EditItemTemplate pole z pole do ItemTemplate. Dále umístěte $ před TextBox a nastavte jeho ID vlastnost na UnitPrice a jeho Columns vlastnost na 8 .

Přidejte také compareValidator k UnitPrice s ItemTemplate , aby se zajistilo, že hodnota zadaná uživatelem je platná hodnota měny větší nebo rovna 0,00 USD. Nastavte vlastnost validátoru ControlToValidate na UnitPrice, jeho ErrorMessage vlastnost na Hodnotu Je nutné zadat platnou hodnotu měny. Vynechat všechny symboly měny, jeho Text vlastnost *, Type jeho vlastnost Currency, jeho Operator vlastnost GreaterThanEquala ValueToCompare vlastnost 0 .

Přidání compareValidatoru pro zajištění, že zadaná cena je nezáporná hodnota měny

Obrázek 7: Přidání compareValidatoru pro zajištění, že zadaná cena je nezáporná hodnota měny (kliknutím zobrazíte obrázek plné velikosti)

Discontinued Pro TemplateField můžete použít CheckBox již definovaný v objektu ItemTemplate. Jednoduše nastavte jeho ID na Hodnotu Ukončeno a jeho Enabled vlastnost na True.

Krok 3: VytvořeníCategoryNamerozhraní pro úpravy

Rozhraní pro úpravy v CategoryName TemplateField s EditItemTemplate obsahuje TextBox, který zobrazuje hodnotu datového CategoryName pole. Musíme ho nahradit rozevíracím seznamem, který obsahuje seznam možných kategorií.

Poznámka:

Kurz Přizpůsobení rozhraní pro úpravu dat obsahuje důkladnější a ucelenější diskuzi o přizpůsobení šablony tak, aby obsahoval rozevírací seznam místo textového pole. I když jsou zde uvedené kroky hotové, zobrazují se tersely. Podrobnější informace o vytváření a konfiguraci kategorií DropDownList najdete v kurzu Přizpůsobení rozhraní pro úpravu dat.

Přetažení rozevíracího seznamu ze sady nástrojů na CategoryName TemplateField s ItemTemplate, nastavení na ID Categories. V tomto okamžiku bychom obvykle definovali zdroj dat DropDownLists prostřednictvím své inteligentní značky a vytvořili nový ObjectDataSource. To však přidá ObjectDataSource v rámci ItemTemplate, což bude mít za následek ObjectDataSource instance vytvořené pro každý řádek GridView. Místo toho pojďme vytvořit ObjectDataSource mimo GridView s TemplateFields. Ukončete úpravy šablony a přetáhněte objekt ObjectDataSource ze sady nástrojů do Návrháře pod ProductsDataSource ObjectDataSource. Pojmenujte nový ObjectDataSource CategoriesDataSource a nakonfigurujte ho tak, aby používal metodu CategoriesBLL třídy s GetCategories .

Konfigurace ObjectDataSource pro použití kategorieBLL třídy

Obrázek 8: Konfigurace ObjectDataSource pro použití CategoriesBLL třídy (kliknutím zobrazíte obrázek s plnou velikostí)

Načtení dat kategorie pomocí getCategories – metoda

Obrázek 9: Načtení dat kategorie pomocí GetCategories metody (kliknutím zobrazíte obrázek s plnou velikostí)

Vzhledem k tomu, že se tento ObjectDataSource používá pouze k načtení dat, nastavte rozevírací seznamy na kartách UPDATE a DELETE na (Žádné). Dokončete průvodce kliknutím na Dokončit.

Nastavte rozevírací seznamy na kartách UPDATE a DELETE na (Žádné).

Obrázek 10: Nastavení rozevíracích seznamů na kartách UPDATE a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce CategoriesDataSource by deklarativní kód měl vypadat takto:

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

CategoriesDataSource Po vytvoření a nakonfigurování se vraťte do CategoryName TemplateField s ItemTemplate a z inteligentní značky DropDownList klikněte na odkaz Zvolit zdroj dat. V průvodci konfigurací zdroje dat vyberte CategoriesDataSource možnost z prvního rozevíracího seznamu a zvolte, že se CategoryName má použít pro zobrazení a CategoryID jako hodnotu.

Vytvoření vazby rozevíracího seznamu k KategorieDataSource

Obrázek 11: Vytvoření vazby rozevíracího seznamu k CategoriesDataSource seznamu (kliknutím zobrazíte obrázek s plnou velikostí)

V tomto okamžiku Categories dropDownList zobrazí seznam všech kategorií, ale zatím automaticky nevybere odpovídající kategorii produktu vázaného na řádek GridView. Abychom toho dosáhli, musíme nastavit Categories DropDownList s SelectedValue na hodnotu produktu CategoryID . Klikněte na odkaz Upravit datové vazby z inteligentní značky DropDownList a přidružte SelectedValue vlastnost k datovému CategoryID poli, jak je znázorněno na obrázku 12.

Vytvoření vazby hodnoty CategoryID produktu na vlastnost DropDownList s SelectedValue

Obrázek 12: Vytvoření vazby CategoryID hodnoty produktu k vlastnosti DropDownList s SelectedValue

Jeden poslední problém zůstává: Pokud produkt nemá zadanou CategoryID hodnotu, příkaz pro vazbu SelectedValue dat způsobí výjimku. Důvodem je to, že Rozevírací seznam obsahuje pouze položky pro kategorie a nenabízí možnost pro produkty, které mají NULL hodnotu databáze pro CategoryID. Chcete-li to napravit, nastavte DropDownList s AppendDataBoundItems vlastnost True a přidat novou položku do DropDownList, vynecháte Value vlastnost z deklarativní syntaxe. To znamená, že Categories deklarativní syntaxe DropDownList vypadá takto:

<asp:DropDownList ID="Categories" runat="server" AppendDataBoundItems="True" 
    DataSourceID="CategoriesDataSource" DataTextField="CategoryName" 
    DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'>
    <asp:ListItem Value=">-- Select One --</asp:ListItem>
</asp:DropDownList>

Všimněte si, že parametr <asp:ListItem Value=""> -- Select One - má jeho Value atribut explicitně nastavený na prázdný řetězec. Pro podrobnější diskuzi o tom, proč je tato další položka DropDownList potřebná ke zpracování NULL případu a důvodu přiřazení Value vlastnosti k prázdnému řetězci, najdete v kurzu Přizpůsobení rozhraní pro úpravu dat.

Poznámka:

Existuje potenciální problém s výkonem a škálovatelností, který stojí za zmínku. Vzhledem k tomu, že každý řádek má DropDownList, který používá CategoriesDataSource jako zdroj dat, CategoriesBLL metoda třídy s GetCategories bude volána nkrát na stránku, kde n je počet řádků v GridView. Tato n volání mají GetCategories za následek n dotazů do databáze. Tento dopad na databázi může být menší díky ukládání vrácených kategorií do mezipaměti pro jednotlivé požadavky nebo prostřednictvím vrstvy ukládání do mezipaměti pomocí závislosti sql do mezipaměti nebo velmi krátké vypršení platnosti založeného na čase.

Krok 4: Dokončení rozhraní pro úpravy

Provedli jsme řadu změn v šablonách GridView bez pozastavení, abychom viděli průběh. Chvilku si prohlédněte průběh v prohlížeči. Jak ukazuje obrázek 13, každý řádek se vykreslí pomocí jeho ItemTemplate, který obsahuje rozhraní pro úpravy buněk.

Každý řádek GridView je upravitelný.

Obrázek 13: Každý řádek GridView je upravitelný (kliknutím zobrazíte obrázek s plnou velikostí)

V tuto chvíli bychom se měli postarat o několik menších problémů s formátováním. Nejprve si všimněte, že UnitPrice hodnota obsahuje čtyři desetinné čárky. Chcete-li tento problém vyřešit, vraťte se do UnitPrice TemplateField s ItemTemplate a z inteligentní značky TextBox s klikněte na odkaz Upravit vazby dat. Dále určete, že Text vlastnost by měla být formátována jako číslo.

Formátování textové vlastnosti jako čísla

Obrázek 14: Formátování Text vlastnosti jako čísla

Za druhé, zarovnáme zaškrtávací políčko do Discontinued sloupce (místo toho, aby bylo zarovnané doleva). Klikněte na Upravit sloupce z inteligentní značky GridView a vyberte Discontinued TemplateField ze seznamu polí v levém dolním rohu. Přejděte k podrobnostem ItemStyle a nastavte HorizontalAlign vlastnost Na střed, jak je znázorněno na obrázku 15.

Zacentrujte ukončené zaškrtávací políčko.

Obrázek 15: Na střed zaškrtávacího Discontinued políčka

Dále na stránku přidejte ovládací prvek ValidationSummary a nastavte jeho ShowMessageBox vlastnost a jeho ShowSummary vlastnost na FalseTrue . Přidejte také webové ovládací prvky tlačítka, které po kliknutí aktualizují změny uživatele. Konkrétně přidejte dva ovládací prvky Button Web, jeden nad GridView a jeden pod ním, nastavení obou vlastností ovládacích prvků Text na Aktualizovat produkty .

Vzhledem k tomu, že rozhraní pro úpravy GridView je definováno v jeho TemplateFields ItemTemplate s, EditItemTemplate jsou nadbytečné a mohou být odstraněny.

Po provedení výše uvedených změn formátování by přidání ovládacích prvků Tlačítko a odebrání nepotřebných EditItemTemplate výrazů měla deklarativní syntaxe stránky vypadat takto:

<p>
    <asp:Button ID="UpdateAllProducts1" runat="server" Text="Update Products" />
</p>
<p>
    <asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
        AllowPaging="True" AllowSorting="True">
        <Columns>
            <asp:TemplateField HeaderText="Product" SortExpression="ProductName">
                <ItemTemplate>
                    <asp:TextBox ID="ProductName" runat="server" 
                        Text='<%# Bind("ProductName") %>'></asp:TextBox>
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" 
                        ControlToValidate="ProductName"
                        ErrorMessage="You must provide the product's name." 
                        runat="server">*</asp:RequiredFieldValidator>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Category" 
                SortExpression="CategoryName">
                <ItemTemplate>
                    <asp:DropDownList ID="Categories" runat="server" 
                        AppendDataBoundItems="True" 
                        DataSourceID="CategoriesDataSource"
                        DataTextField="CategoryName" 
                        DataValueField="CategoryID" 
                        SelectedValue='<%# Bind("CategoryID") %>'>
                        <asp:ListItem>-- Select One --</asp:ListItem>
                    </asp:DropDownList>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Price" 
                SortExpression="UnitPrice">
                <ItemTemplate>
                    $<asp:TextBox ID="UnitPrice" runat="server" Columns="8" 
                        Text='<%# Bind("UnitPrice", "{0:N}") %>'></asp:TextBox>
                    <asp:CompareValidator ID="CompareValidator1" runat="server" 
                        ControlToValidate="UnitPrice"
                        ErrorMessage="You must enter a valid currency value. 
                                      Please omit any currency symbols."
                        Operator="GreaterThanEqual" Type="Currency" 
                        ValueToCompare="0">*</asp:CompareValidator>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
                <ItemTemplate>
                    <asp:CheckBox ID="Discontinued" runat="server" 
                        Checked='<%# Bind("Discontinued") %>' />
                </ItemTemplate>
                <ItemStyle HorizontalAlign="Center" />
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</p>
<p>
    <asp:Button ID="UpdateAllProducts2" runat="server" Text="Update Products" />
    <asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}"
        SelectMethod="GetProducts" TypeName="ProductsBLL">
    </asp:ObjectDataSource>
    <asp:ObjectDataSource ID="CategoriesDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}"
        SelectMethod="GetCategories" TypeName="CategoriesBLL">
    </asp:ObjectDataSource>
    <asp:ValidationSummary ID="ValidationSummary1" runat="server" 
        ShowMessageBox="True" ShowSummary="False" />
</p>

Obrázek 16 znázorňuje tuto stránku po přidání ovládacích prvků Button Web a provedených změnách formátování v prohlížeči.

Stránka teď obsahuje dvě tlačítka aktualizačních produktů.

Obrázek 16: Stránka teď obsahuje dvě tlačítka aktualizačních produktů (kliknutím zobrazíte obrázek s plnou velikostí)

Krok 5: Aktualizace produktů

Když uživatel navštíví tuto stránku, provede změny a potom klikne na jedno ze dvou tlačítek Aktualizovat produkty. V tomto okamžiku musíme nějak uložit uživatelem zadané hodnoty pro každý řádek do ProductsDataTable instance a pak ji předat metodě BLL, která pak předá danou ProductsDataTable instanci metodě DAL s UpdateWithTransaction . Metoda UpdateWithTransaction , kterou jsme vytvořili v předchozím kurzu, zajišťuje, že se dávka změn aktualizuje jako atomická operace.

Vytvořte metodu s názvem BatchUpdate a BatchUpdate.aspx.vb přidejte následující kód:

Private Sub BatchUpdate()
    ' Enumerate the GridView's Rows collection and create a ProductRow
    Dim productsAPI As New ProductsBLL()
    Dim products As Northwind.ProductsDataTable = productsAPI.GetProducts()
    For Each gvRow As GridViewRow In ProductsGrid.Rows
        ' Find the ProductsRow instance in products that maps to gvRow
        Dim productID As Integer = _
            Convert.ToInt32(ProductsGrid.DataKeys(gvRow.RowIndex).Value)
        Dim product As Northwind.ProductsRow = products.FindByProductID(productID)
        If product IsNot Nothing Then
            ' Programmatically access the form field elements in the 
            ' current GridViewRow
            Dim productName As TextBox = _
                CType(gvRow.FindControl("ProductName"), TextBox)
            Dim categories As DropDownList = _
                CType(gvRow.FindControl("Categories"), DropDownList)
            Dim unitPrice As TextBox = _
                CType(gvRow.FindControl("UnitPrice"), TextBox)
            Dim discontinued As CheckBox = _
                CType(gvRow.FindControl("Discontinued"), CheckBox)
            ' Assign the user-entered values to the current ProductRow
            product.ProductName = productName.Text.Trim()
            If categories.SelectedIndex = 0 Then 
                product.SetCategoryIDNull() 
            Else 
                product.CategoryID = Convert.ToInt32(categories.SelectedValue)
            End If
            If unitPrice.Text.Trim().Length = 0 Then 
                product.SetUnitPriceNull() 
            Else 
                product.UnitPrice = Convert.ToDecimal(unitPrice.Text)
            End If
            product.Discontinued = discontinued.Checked
        End If
    Next
    ' Now have the BLL update the products data using a transaction
    productsAPI.UpdateWithTransaction(products)
End Sub

Tato metoda začíná získáním všech produktů zpět do ProductsDataTable volání metody BLL.GetProducts Potom vytvoří ProductGrid výčet kolekce GridView sRows. Kolekce Rows obsahuje GridViewRow instanci pro každý řádek zobrazený v GridView. Vzhledem k tomu, že na stránce zobrazujeme maximálně deset řádků, kolekce GridView Rows nebude obsahovat více než deset položek.

Pro každý řádek, který ProductID je uchopen z DataKeys kolekce a je vybrán z ProductsRow příslušného ProductsDataTableřádku . Na čtyři vstupní ovládací prvky TemplateField se odkazuje prostřednictvím kódu programu a jejich hodnoty přiřazené vlastnostem ProductsRow instance. Poté, co byly hodnoty řádků GridView použity k aktualizaci ProductsDataTable, je předána do BLL s UpdateWithTransaction metoda, která, jak jsme viděli v předchozím kurzu, jednoduše volá do METODY DAL s UpdateWithTransaction .

Algoritmus dávkové aktualizace použitý pro tento kurz aktualizuje každý řádek, ProductsDataTable který odpovídá řádku v GridView bez ohledu na to, jestli byly informace o produktu změněny. I když tyto nevidomé aktualizace obvykle nejsou problém s výkonem, můžou vést k nadbytečným záznamům, pokud auditujete změny v tabulce databáze. V kurzu provádění dávkových aktualizací jsme prozkoumali rozhraní dávkové aktualizace pomocí dataListu a přidali kód, který by aktualizoval pouze ty záznamy, které byly skutečně upraveny uživatelem. V případě potřeby můžete použít techniky provádění aktualizací služby Batch k aktualizaci kódu v tomto kurzu.

Poznámka:

Při vytváření vazby zdroje dat k Objektu GridView prostřednictvím inteligentní značky visual Studio automaticky přiřadí hodnotu primárního klíče zdroje dat k vlastnosti GridView DataKeyNames . Pokud jste objekt ObjectDataSource nevytvořili vazbu na GridView prostřednictvím inteligentní značky GridView s, jak je popsáno v kroku 1, budete muset vlastnost GridView s DataKeyNames nastavit na ProductID, aby bylo možné získat přístup k ProductID hodnotě pro každý řádek prostřednictvím DataKeys kolekce.

Kód použitý v BatchUpdate metodách BLL je podobný tomu, že v metodách BLL UpdateProduct je hlavní rozdíl v tom, že v UpdateProduct metodách se z architektury načte pouze jedna ProductRow instance. Kód, který přiřazuje vlastnosti je ProductRow stejný mezi UpdateProducts metodami a kódem v rámci For Each smyčky v BatchUpdate, stejně jako celkový vzor.

K dokončení tohoto kurzu musíme metodu BatchUpdate vyvolat při kliknutí na některé z tlačítek Update Products. Vytvořte obslužné rutiny událostí pro Click události těchto dvou ovládacích prvků Button a přidejte do obslužných rutin událostí následující kód:

BatchUpdate()
ClientScript.RegisterStartupScript(Me.GetType(), "message", _
    "alert('The products have been updated.');", True)

První volání je provedeno BatchUpdate. Dále se ClientScript vlastnost používá k vložení JavaScriptu, který zobrazí pole se zprávou, která čte produkty byly aktualizovány.

Otestujte tento kód za minutu. Navštivte prohlížeč, upravte BatchUpdate.aspx několik řádků a klikněte na jedno z tlačítek Aktualizovat produkty. Za předpokladu, že nedošlo k žádným chybám ověření vstupu, by se měla zobrazit zpráva se zprávou, která čte produkty, které byly aktualizovány. Pokud chcete ověřit atomicitu aktualizace, zvažte přidání náhodného CHECK omezení, jako je ten, který zakáže UnitPrice hodnoty 1234,56. Potom upravte BatchUpdate.aspxpočet záznamů a ujistěte se, že je jedna z hodnot produktu UnitPrice nastavena na zakázáno hodnotu ( 1234,56 ). Výsledkem by měla být chyba při kliknutí na aktualizační produkty s dalšími změnami během této dávkové operace, která se vrátila zpět k původním hodnotám.

AlternativníBatchUpdatemetoda

Metoda BatchUpdate , kterou jsme právě prozkoumali , načte všechny produkty z metody BLL a GetProducts pak aktualizuje pouze ty záznamy, které se zobrazí v GridView. Tento přístup je ideální, pokud GridView nepoužívá stránkování, ale pokud ano, může existovat stovky, tisíce nebo desítky tisíc produktů, ale pouze deset řádků v GridView. V takovém případě je získání všech produktů z databáze pouze k úpravě 10 z nich menší než ideální.

U těchto typů situací zvažte místo toho použití následující BatchUpdateAlternate metody:

Private Sub BatchUpdateAlternate()
    ' Enumerate the GridView's Rows collection and create a ProductRow
    Dim productsAPI As New ProductsBLL()
    Dim products As New Northwind.ProductsDataTable()
    For Each gvRow As GridViewRow In ProductsGrid.Rows
        ' Create a new ProductRow instance
        Dim productID As Integer = _
            Convert.ToInt32(ProductsGrid.DataKeys(gvRow.RowIndex).Value)
        Dim currentProductDataTable As Northwind.ProductsDataTable = _
            productsAPI.GetProductByProductID(productID)
        If currentProductDataTable.Rows.Count > 0 Then
            Dim product As Northwind.ProductsRow = currentProductDataTable(0)
            Dim productName As TextBox = _
                CType(gvRow.FindControl("ProductName"), TextBox)
            Dim categories As DropDownList = _
                CType(gvRow.FindControl("Categories"), DropDownList)
            Dim unitPrice As TextBox = _
                CType(gvRow.FindControl("UnitPrice"), TextBox)
            Dim discontinued As CheckBox = _
                CType(gvRow.FindControl("Discontinued"), CheckBox)
            ' Assign the user-entered values to the current ProductRow
            product.ProductName = productName.Text.Trim()
            If categories.SelectedIndex = 0 Then 
                product.SetCategoryIDNull() 
            Else 
                product.CategoryID = Convert.ToInt32(categories.SelectedValue)
            End If
            If unitPrice.Text.Trim().Length = 0 Then 
                product.SetUnitPriceNull() 
            Else 
                product.UnitPrice = Convert.ToDecimal(unitPrice.Text)
            End If
            product.Discontinued = discontinued.Checked
            ' Import the ProductRow into the products DataTable
            products.ImportRow(product)
        End If
    Next
    ' Now have the BLL update the products data using a transaction
    productsAPI.UpdateProductsWithTransaction(products)
End Sub

BatchMethodAlternate začíná vytvořením nového prázdného ProductsDataTable názvu products. Pak prochází kolekci GridView a Rows pro každý řádek získá konkrétní informace o produktu pomocí metody BLL s GetProductByProductID(productID) . Načtená ProductsRow instance má své vlastnosti aktualizované stejným způsobem jako BatchUpdate, ale po aktualizaci řádku, který je importován do ProductsDataTable products metody DataTable sImportRow(DataRow).

For Each Po dokončení smyčky products obsahuje jedna ProductsRow instance pro každý řádek v GridView. Vzhledem k tomu, že každá instance ProductsRow byla přidána do products (místo aktualizace), pokud ji UpdateWithTransaction nevidomě předáme metodě, ProductsTableAdapter pokusí se vložit všechny záznamy do databáze. Místo toho musíme určit, že každý z těchto řádků byl změněn (nepřidá se).

Toho lze dosáhnout přidáním nové metody do BLL s názvem UpdateProductsWithTransaction. UpdateProductsWithTransaction, jak je znázorněno níže, nastaví RowState všechny instance v ProductsDataTable sadě a Modified pak předá ProductsDataTable metodu DAL UpdateWithTransaction ProductsRow.

Public Function UpdateProductsWithTransaction _
    (ByVal products As Northwind.ProductsDataTable) As Integer
    ' Mark each product as Modified
    products.AcceptChanges()
    For Each product As Northwind.ProductsRow In products
        product.SetModified()
    Next
    ' Update the data via a transaction
    Return UpdateWithTransaction(products)
End Function

Shrnutí

GridView poskytuje integrované možnosti úprav pro jednotlivé řádky, ale nemá podporu pro vytváření plně upravitelných rozhraní. Jak jsme viděli v tomto kurzu, taková rozhraní jsou možná, ale vyžadují trochu práce. Chcete-li vytvořit GridView, kde je každý řádek upravitelný, musíme převést pole GridView na TemplateFields a definovat rozhraní pro úpravy v rámci ItemTemplate s. Kromě toho musí být na stránku přidány ovládací prvky Update All -type Button Web, oddělené od GridView. Tyto obslužné rutiny událostí Tlačítka Click musí vytvořit výčet kolekce GridView s Rows , uložit změny do ProductsDataTablea a předat aktualizované informace do příslušné metody BLL.

V dalším kurzu se dozvíte, jak vytvořit rozhraní pro dávkové odstraňování. Každý řádek GridView bude obsahovat zaškrtávací políčko a místo tlačítek Aktualizovat vše -type budeme mít tlačítka Odstranit vybrané řádky.

Šť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 Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí recenzenti tohoto kurzu byli Teresa Murphy a David Suru. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.