Sdílet prostřednictvím


Dávkové vkládání (VB)

Scott Mitchell

Stáhnout PDF

Zjistěte, jak v jedné operaci vložit více databázových záznamů. Ve vrstvě uživatelského rozhraní rozšiřujeme GridView, aby uživatel mohl zadat více nových záznamů. Ve vrstvě přístupu k datům zabalíme několik operací Vložení v rámci transakce, abychom zajistili, že všechna vložení budou úspěšná nebo vrácena zpět.

Úvod

V kurzu Dávkové aktualizace jsme se podívali na přizpůsobení ovládacího prvku GridView tak, aby se představilo rozhraní, ve kterém bylo možné upravovat více záznamů. Uživatel, který stránku navštíví, může provést řadu změn a pak jedním kliknutím na tlačítko provést dávkovou aktualizaci. V situacích, kdy uživatelé často aktualizují mnoho záznamů najednou, může takové rozhraní ve srovnání s výchozími funkcemi pro úpravy jednotlivých řádků, které byly poprvé prozkoumány v kurzu Přehled vkládání, aktualizace a odstraňování dat , uložit nespočet kliknutí a kontextových přepínačů klávesnice na myš.

Tento koncept lze použít také při přidávání záznamů. Představte si, že tady v Northwind Traders běžně přijímáme zásilky od dodavatelů, které obsahují řadu produktů pro určitou kategorii. Jako příklad můžeme obdržet zásilku šesti různých čajových a kávových produktů od společnosti Tokyo Traders. Pokud uživatel zadá šest produktů po jednom prostřednictvím ovládacího prvku DetailsView, bude muset znovu a znovu zvolit mnoho stejných hodnot: bude muset zvolit stejnou kategorii (Nápoje), stejného dodavatele (Tokyo Traders), stejnou ukončenou hodnotu (False) a stejné jednotky na hodnotě objednávky (0). Toto opakované zadávání dat je nejen časově náročné, ale také náchylné k chybám.

S trochou práce můžeme vytvořit dávkové vkládání rozhraní, které uživateli umožní vybrat dodavatele a kategorii jednou, zadat řadu názvů produktů a jednotkových cen a potom kliknutím na tlačítko přidat nové produkty do databáze (viz Obrázek 1). Při přidání každého produktu se jeho ProductName a UnitPrice datovým polím přiřazují hodnoty zadané v textových polích, zatímco hodnoty CategoryID a SupplierID jsou přiřazeny hodnoty z rozevíracích seznamů v horní části formuláře. Hodnoty Discontinued a UnitsOnOrder jsou nastaveny na pevně zakódované hodnoty False a 0 v uvedeném pořadí.

Rozhraní dávkového vkládání

Obrázek 1: Rozhraní Batch Inserting Interface (kliknutím zobrazíte obrázek v plné velikosti)

V tomto kurzu vytvoříme stránku, která implementuje rozhraní dávkového vkládání znázorněné na obrázku 1. Stejně jako v předchozích dvou kurzech zabalíme vložení do rozsahu transakce, abychom zajistili atomicitu. Pojďme začít!

Krok 1: Vytvoření rozhraní pro zobrazení

Tento kurz se bude skládat z jedné stránky, která je rozdělená do dvou oblastí: oblasti zobrazení a oblasti vkládání. Rozhraní zobrazení, které vytvoříme v tomto kroku, zobrazuje produkty v zobrazení GridView a obsahuje tlačítko s názvem Zpracovat dodávku produktu. Po kliknutí na toto tlačítko se rozhraní zobrazení nahradí rozhraním pro vkládání, které je znázorněno na obrázku 1. Rozhraní zobrazení se vrátí po kliknutí na tlačítka Přidat produkty z dodávky nebo Zrušit. Rozhraní pro vkládání vytvoříme v kroku 2.

Při vytváření stránky, která má dvě rozhraní, z nichž je současně viditelná pouze jedno, je každé rozhraní obvykle umístěno v ovládacím prvku Panel Web, který slouží jako kontejner pro jiné ovládací prvky. Proto bude naše stránka mít dva ovládací prvky Panel jeden pro každé rozhraní.

Začněte tím, že BatchInsert.aspx otevřete stránku ve BatchData složce a přetáhnete panel z panelu nástrojů do Designer (viz obrázek 2). Nastavte vlastnost Panel s ID na DisplayInterface. Při přidávání panelu do Designer jsou jeho Height vlastnosti a Width nastaveny na 50 px a 125 px v uvedeném pořadí. Vymažte tyto hodnoty vlastností z okno Vlastnosti.

Přetažení panelu ze sady nástrojů na Designer

Obrázek 2: Přetažení panelu ze sady nástrojů na Designer (kliknutím zobrazíte obrázek v plné velikosti)

Dále přetáhněte ovládací prvek Button a GridView do panelu. Nastavte vlastnost Button s ID na ProcessShipment a její Text vlastnost na Zpracovat dodávku produktu. Nastavte vlastnost GridView s ID na ProductsGrid a z její inteligentní značky ji vytvořte vazbu na nový ObjectDataSource s názvem ProductsDataSource. Nakonfigurujte ObjectDataSource tak, aby načítá data z ProductsBLL metody třídy s GetProducts . Vzhledem k tomu, že se toto zobrazení GridView používá jenom k zobrazení dat, nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné). Kliknutím na Dokončit dokončete průvodce konfigurací zdroje dat.

Zobrazení dat vrácených metodou GetProducts třídy ProductsBLL

Obrázek 3: Zobrazení dat vrácených metodou ProductsBLL třídy GetProducts (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte Drop-Down Seznamy na kartách UPDATE, INSERT a DELETE na (Žádné).

Obrázek 4: Nastavení Drop-Down Seznamy na kartách UPDATE, INSERT a DELETE na (Žádný) (Kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce ObjectDataSource přidá Visual Studio boundFields a CheckBoxField pro pole s daty produktu. Odeberte všechna pole kromě ProductNamepolí , CategoryNameSupplierName, , UnitPricea Discontinued . Nebojte se provést jakékoli estetické přizpůsobení. Rozhodl jsem se pole naformátovat UnitPrice jako hodnotu měny, změnit pořadí polí a přejmenovat několik hodnot polí HeaderText . Také nakonfigurujte GridView tak, aby zahrnoval podporu stránkování a řazení zaškrtnutím políček Povolit stránkování a Povolit řazení v inteligentní značce GridView s.

Po přidání ovládacích prvků Panel, Button, GridView a ObjectDataSource a přizpůsobení polí GridView s by deklarativní značky stránky měly vypadat nějak takto:

<asp:Panel ID="DisplayInterface" runat="server">
    <p>
        <asp:Button ID="ProcessShipment" runat="server" 
            Text="Process Product Shipment" /> 
    </p>
    <asp:GridView ID="ProductsGrid" runat="server" AllowPaging="True" 
        AllowSorting="True" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="ProductsDataSource">
        <Columns>
            <asp:BoundField DataField="ProductName" HeaderText="Product" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                ReadOnly="True" SortExpression="CategoryName" />
            <asp:BoundField DataField="SupplierName" HeaderText="Supplier" 
                ReadOnly="True" SortExpression="SupplierName" />
            <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                HeaderText="Price" HtmlEncode="False" 
                SortExpression="UnitPrice">
                <ItemStyle HorizontalAlign="Right" />
            </asp:BoundField>
            <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" 
                SortExpression="Discontinued">
                <ItemStyle HorizontalAlign="Center" />
            </asp:CheckBoxField>
        </Columns>
    </asp:GridView>
    <asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}"
        SelectMethod="GetProducts" TypeName="ProductsBLL">
    </asp:ObjectDataSource>
</asp:Panel>

Všimněte si, že značky pro Button a GridView se zobrazí v rámci úvodní a uzavírací <asp:Panel> značky. Vzhledem k tomu, že se tyto ovládací prvky nacházejí v panelu DisplayInterface , můžeme je skrýt jednoduchým nastavením vlastnosti Panel s Visible na False. Krok 3 se zabývá programovou změnou vlastnosti Panel s Visible v reakci na kliknutí na tlačítko, aby se jedno rozhraní zobrazilo a druhé skrývalo.

Udělejte si chvilku a podívejte se na průběh v prohlížeči. Jak ukazuje obrázek 5, mělo by se zobrazit tlačítko Zpracovat dodávku produktů nad GridView, které zobrazuje seznam produktů po deseti najednou.

GridView Seznamy možnosti řazení a stránkování produktů a nabídek

Obrázek 5: GridView Seznamy možnosti řazení a stránkování produktů a nabídek (kliknutím zobrazíte obrázek v plné velikosti)

Krok 2: Vytvoření rozhraní pro vkládání

Po dokončení rozhraní pro zobrazení jsme připraveni vytvořit rozhraní pro vkládání. Pro účely tohoto kurzu vytvoříme rozhraní pro vkládání, které vyzve k zadání jedné hodnoty dodavatele a kategorie a umožní uživateli zadat až pět názvů produktů a jednotkových cen. Pomocí tohoto rozhraní může uživatel přidat jeden až pět nových produktů, které mají stejnou kategorii a dodavatele, ale mají jedinečné názvy a ceny produktů.

Začněte přetažením panelu ze sady nástrojů do Designer a jeho umístěním pod existující DisplayInterface panel. Nastavte ID vlastnost tohoto nově přidaného panelu na InsertingInterface a nastavte jeho Visible vlastnost na False. Přidáme kód, který nastaví InsertingInterface vlastnost Panel Visible na hodnotu True v kroku 3. Vymažte také hodnoty panelů Height a Width vlastností.

Dále musíme vytvořit rozhraní pro vkládání, které bylo znázorněno zpět na obrázku 1. Toto rozhraní lze vytvořit pomocí různých technik HTML, ale použijeme poměrně přímočarou: čtyřsloupce, sedmiřádkovou tabulku.

Poznámka

Při zadávání značek pro elementy HTML <table> dávám přednost zobrazení Zdroj. I když sada Visual Studio obsahuje nástroje pro přidávání <table> prvků prostřednictvím Designer, Designer se zdá být příliš ochotné vložit do značek nezaškrtané style nastavení. Po vytvoření značky <table> se obvykle vrátím do Designer přidat webové ovládací prvky a nastavit jejich vlastnosti. Při vytváření tabulek s předem určenými sloupci a řádky dávám přednost použití statického html než webového ovládacího prvku Tabulka, protože ke všem webovým ovládacím prvkům umístěným v ovládacím prvku Table Web lze přistupovat pouze pomocí FindControl("controlID") vzoru. Používám však ovládací prvky Table Web pro tabulky s dynamickou velikostí (ty, jejichž řádky nebo sloupce jsou založené na některých kritériích databáze nebo uživatelem zadaných), protože ovládací prvek Tabulka web lze vytvořit programově.

Do značek InsertingInterface panelu <asp:Panel> zadejte následující kód:

<table class="DataWebControlStyle" cellspacing="0">
    <tr class="BatchInsertHeaderRow">
        <td class="BatchInsertLabel">Supplier:</td>
        <td></td>
        <td class="BatchInsertLabel">Category:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertAlternatingRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertAlternatingRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertFooterRow">
        <td colspan="4">
        </td>
    </tr>
</table>

Tato <table> značka zatím neobsahuje žádné webové ovládací prvky, přidáme je na chvíli. Všimněte si, že každý <tr> prvek obsahuje konkrétní nastavení třídy CSS: BatchInsertHeaderRow pro řádek záhlaví, kam se přesune dodavatel a kategorie DropDownLists; BatchInsertFooterRow pro řádek zápatí, kam budou tlačítka Přidat produkty z dodávky a Zrušit; a střídavě BatchInsertRow a BatchInsertAlternatingRow hodnoty pro řádky, které budou obsahovat ovládací prvky TextBox s produktem a jednotkovou cenou. Vytvořil(a) jsem v Styles.css souboru odpovídající třídy CSS, aby se rozhraní pro vkládání podobaly ovládacím prvkům GridView a DetailsView, které jsme použili v těchto kurzech. Tyto třídy CSS jsou zobrazeny níže.

/*** Styles for ~/BatchData/BatchInsert.aspx tutorial ***/
.BatchInsertLabel
{
    font-weight: bold;
    text-align: right;
}
.BatchInsertHeaderRow td
{
    color: White;
    background-color: #900;
    padding: 11px;
}
.BatchInsertFooterRow td
{
    text-align: center;
    padding-top: 5px;
}
.BatchInsertRow
{
}
.BatchInsertAlternatingRow
{
    background-color: #fcc;
}

Po zadání tohoto kódu se vraťte do návrhového zobrazení. V Designer by se <table> tato tabulka měla zobrazit jako tabulka se čtyřmi sloupci se sedmi řádky, jak je znázorněno na obrázku 6.

Rozhraní pro vkládání se skládá z tabulky se čtyřmi sloupci Seven-Row.

Obrázek 6: Rozhraní pro vkládání se skládá ze čtyřsloupkové tabulky Seven-Row (kliknutím zobrazíte obrázek v plné velikosti)

Teď jsme připraveni přidat webové ovládací prvky do rozhraní pro vkládání. Přetáhněte dva rozevírací seznamy z panelu nástrojů do příslušných buněk v tabulce , jedna pro dodavatele a jedna pro kategorii.

Nastavte vlastnost DropDownList s ID dodavatele na Suppliers a vytvořte vazbu k novému objektu ObjectDataSource s názvem SuppliersDataSource. Nakonfigurujte nový ObjectDataSource tak, aby načetl data z SuppliersBLL metody třídy s GetSuppliers , a nastavte rozevírací seznam UPDATE tab na (None). Dokončete průvodce kliknutím na Dokončit.

Nakonfigurujte ObjectDataSource tak, aby používal metodu SuppliersBLL Class s GetSuppliers.

Obrázek 7: Konfigurace objektu ObjectDataSource tak, aby používal metodu SuppliersBLL Class s GetSuppliers (kliknutím zobrazíte obrázek v plné velikosti)

Nechte rozevírací seznam Suppliers zobrazit CompanyName datové pole a použít SupplierID datové pole jako jeho ListItem hodnoty.

Zobrazení datového pole CompanyName a použití Id dodavatele jako hodnoty

Obrázek 8: Zobrazení datového CompanyName pole a použití SupplierID jako hodnoty (kliknutím zobrazíte obrázek v plné velikosti)

Pojmenujte druhý rozevírací seznam Categories a vytvořte vazbu k novému objektu ObjectDataSource s názvem CategoriesDataSource. CategoriesDataSource Nakonfigurujte ObjectDataSource tak, aby používal metodu CategoriesBLL třídy sGetCategories. Nastavte rozevírací seznamy na kartách UPDATE a DELETE na (None) a kliknutím na Dokončit dokončete průvodce. Nakonec nechte DropDownList zobrazit CategoryName datové pole a použít CategoryID jako hodnotu hodnotu.

Po přidání těchto dvou rozevíracích seznamů a jejich vazbě na správně nakonfigurované ObjectDataSources by vaše obrazovka měla vypadat podobně jako na obrázku 9.

Řádek záhlaví nyní obsahuje rozevírací seznamy dodavatelů a kategorií.

Obrázek 9: Řádek záhlaví teď obsahuje Suppliers rozevírací seznamy a Categories (kliknutím zobrazíte obrázek v plné velikosti)

Teď musíme vytvořit textová pole, abychom shromáždili název a cenu každého nového produktu. Přetáhněte ovládací prvek TextBox z panelu nástrojů na Designer pro každý z pěti řádků názvu produktu a ceny. ID Nastavte vlastnosti textových polí na ProductName1, UnitPrice1, ProductName2, UnitPrice2ProductName3, , UnitPrice3atd.

Přidejte CompareValidator za každé pole textových polí jednotkové ceny a nastavte ControlToValidate vlastnost na odpovídající IDhodnotu . Vlastnost také nastavte Operator na GreaterThanEqual, ValueToCompare na 0 a Type na Currency. Tato nastavení instruují CompareValidator, aby zajistil, že cena, pokud je zadána, je platná hodnota měny, která je větší než nebo rovna nule. Text Nastavte vlastnost na *a ErrorMessage na Hodnotu Cena musí být větší nebo rovna nule. Vyněnejte také symboly měny.

Poznámka

Rozhraní pro vkládání neobsahuje žádné ovládací prvky RequiredFieldValidator, i když ProductName pole v Products tabulce databáze nepovoluje NULL hodnoty. Je to proto, že chceme, aby uživatel zadal až pět produktů. Pokud například uživatel zadá název produktu a jednotkovou cenu pro první tři řádky a ponechá poslední dva řádky prázdné, přidáme do systému jenom tři nové produkty. Vzhledem k tomu ProductName , že je to povinné, budeme muset programově zkontrolovat, abychom zajistili, že pokud je zadána jednotková cena, je zadána odpovídající hodnota názvu produktu. Touto kontrolou se budeme zabývat v kroku 4.

Při ověřování vstupu uživatele funkce CompareValidator hlásí neplatná data, pokud hodnota obsahuje symbol měny. Přidejte $ před každé z jednotkových cen textových polí, která budou sloužit jako vizuální upozornění, které uživateli dává pokyn, aby při zadávání ceny vynechal symbol měny.

Nakonec přidejte ovládací prvek ValidationSummary v rámci panelu InsertingInterface a jeho vlastnost na TrueShowSummaryFalse.ShowMessageBox Pokud uživatel s těmito nastaveními zadá neplatnou jednotkovou cenu, zobrazí se vedle urážených ovládacích prvků TextBox hvězdička a ValidationSummary zobrazí okno se zprávou na straně klienta, které zobrazuje chybovou zprávu, kterou jsme zadali dříve.

V tomto okamžiku by vaše obrazovka měla vypadat podobně jako obrázek 10.

Vložené rozhraní teď obsahuje textová pole pro názvy a ceny produktů.

Obrázek 10: Vložené rozhraní teď obsahuje textová pole pro názvy a ceny produktů (kliknutím zobrazíte obrázek v plné velikosti)

Dále musíme přidat tlačítka Přidat produkty z dodávky a Zrušit do řádku zápatí. Přetáhněte dva ovládací prvky Button z panelu nástrojů do zápatí rozhraní pro vkládání a nastavujte vlastnosti Tlačítka ID na AddProducts a CancelButton na Text Přidat produkty z dodávky a Zrušit. Kromě toho nastavte CancelButton vlastnost ovládacího prvku s CausesValidation na falsehodnotu .

Nakonec musíme přidat ovládací prvek Label Web, který bude zobrazovat stavové zprávy pro obě rozhraní. Když například uživatel úspěšně přidá novou zásilku produktů, chceme se vrátit do zobrazovacího rozhraní a zobrazit potvrzovací zprávu. Pokud však uživatel zadá cenu nového produktu, ale vynechá název produktu, musíme zobrazit zprávu s upozorněním ProductName , protože pole je povinné. Vzhledem k tomu, že potřebujeme, aby se tato zpráva zobrazila pro obě rozhraní, umístěte ji do horní části stránky mimo panely.

Přetáhněte ovládací prvek Label Web z panelu nástrojů do horní části stránky v Designer. ID Nastavte vlastnost na StatusLabel, vymažte Text vlastnost a nastavte Visible vlastnosti a EnableViewState na False. Jak jsme viděli v předchozích kurzech, nastavení EnableViewState vlastnosti na False nám umožňuje programově změnit hodnoty vlastnosti Label s a nechat je automaticky vrátit zpět na výchozí hodnoty při následném zpětném vrácení. To zjednodušuje kód pro zobrazení stavové zprávy v reakci na nějakou akci uživatele, která zmizí při následném zpětném odeslání. Nakonec nastavte StatusLabel vlastnost ovládacího prvku s CssClass na Warning, což je název třídy CSS definované v Styles.css , která zobrazuje text velkým, kurzívou, tučným a červeným písmem.

Obrázek 11 znázorňuje Designer sady Visual Studio po přidání a konfiguraci popisku.

Umístěte ovládací prvek StatusLabel nad ovládací prvky Dva panely.

Obrázek 11: Umístěte StatusLabel ovládací prvek nad ovládací prvky Dva panely (kliknutím zobrazíte obrázek v plné velikosti)

Krok 3: Přepínání mezi rozhraními pro zobrazení a vkládání

V tomto okamžiku jsme dokončili revize pro naše rozhraní pro zobrazení a vkládání, ale stále nám zbývá dvě úlohy:

  • Přepínání mezi rozhraním pro zobrazení a vkládání
  • Přidání produktů v zásilce do databáze

V současné době je rozhraní zobrazení viditelné, ale rozhraní pro vkládání je skryté. Důvodem je to, že DisplayInterface vlastnost Panel s Visible je nastavená na True hodnotu (výchozí hodnota), zatímco InsertingInterface vlastnost Panel s Visible je nastavená na Falsehodnotu . Pokud chcete přepínat mezi těmito dvěma rozhraními, stačí přepnout hodnotu vlastnosti každého ovládacího prvku Visible .

Když kliknete na tlačítko Zpracovat dodávku produktu, chceme přejít z zobrazovacího rozhraní do rozhraní pro vkládání. Proto vytvořte obslužnou rutinu události pro tuto událost Button s Click , která obsahuje následující kód:

Protected Sub ProcessShipment_Click(sender As Object, e As EventArgs) _
    Handles ProcessShipment.Click
    DisplayInterface.Visible = False
    InsertingInterface.Visible = True
End Sub

Tento kód jednoduše skryje DisplayInterface panel a zobrazí InsertingInterface panel.

Dále vytvořte obslužné rutiny událostí pro ovládací prvky Přidat produkty z dodávky a Tlačítko zrušit v rozhraní pro vkládání. Po kliknutí na některé z těchto tlačítek se musíme vrátit zpět k rozhraní zobrazení. Vytvořte Click obslužné rutiny událostí pro oba ovládací prvky Button tak, aby volaly ReturnToDisplayInterfacemetodu, kterou na chvíli přidáme. Kromě skrytí panelu InsertingInterface a zobrazení panelu DisplayInterfaceReturnToDisplayInterface musí metoda vrátit webové ovládací prvky do jejich stavu před úpravami. To zahrnuje nastavení vlastnosti DropDownLists SelectedIndex na hodnotu 0 a vymazání Text vlastností TextBox ovládacích prvků.

Poznámka

Zvažte, co se může stát, kdybychom před návratem do rozhraní zobrazení nevrátili ovládací prvky do stavu před úpravami. Uživatel může kliknout na tlačítko Zpracovat dodávku produktu, zadat produkty z dodávky a potom kliknout na Přidat produkty z dodávky. To by přidalo produkty a vrátilo uživatele do rozhraní zobrazení. V tomto okamžiku může uživatel chtít přidat další zásilku. Po kliknutí na tlačítko Zpracovat dodávku produktu se vrátí do rozhraní pro vložení, ale výběry DropDownList a TextBox hodnoty budou stále naplněny jejich předchozími hodnotami.

Protected Sub AddProducts_Click(sender As Object, e As EventArgs) _
    Handles AddProducts.Click
    ' TODO: Save the products
    ' Revert to the display interface
    ReturnToDisplayInterface()
End Sub
Protected Sub CancelButton_Click(sender As Object, e As EventArgs) _
    Handles CancelButton.Click
    ' Revert to the display interface
    ReturnToDisplayInterface()
End Sub
Const firstControlID As Integer = 1
Const lastControlID As Integer = 5
Private Sub ReturnToDisplayInterface()
    ' Reset the control values in the inserting interface
    Suppliers.SelectedIndex = 0
    Categories.SelectedIndex = 0
    For i As Integer = firstControlID To lastControlID
        CType(InsertingInterface.FindControl _
            ("ProductName" + i.ToString()), TextBox).Text = String.Empty
        CType(InsertingInterface.FindControl _
            ("UnitPrice" + i.ToString()), TextBox).Text = String.Empty
    Next
    DisplayInterface.Visible = True
    InsertingInterface.Visible = False
End Sub

Obě Click obslužné rutiny událostí jednoduše volají metodu ReturnToDisplayInterface , i když se vrátíme k obslužné rutině události Přidat produkty z dodávky Click v kroku 4 a přidáme kód pro uložení produktů. ReturnToDisplayInterface Začne vrácením Suppliers prvních možností a Categories DropDownLists. Dvě konstanty firstControlID a lastControlID označí hodnoty indexu počátečního a koncového ovládacího prvku použité při pojmenování názvu produktu a jednotkové ceny TextBoxes v rozhraní pro vložení a jsou použity v mezích For smyčky, která nastaví Text vlastnosti ovládacích prvků TextBox zpět na prázdný řetězec. Nakonec se vlastnosti Panely Visible resetují, takže rozhraní pro vkládání je skryté a zobrazí se rozhraní pro zobrazení.

Chvíli si tuto stránku otestujte v prohlížeči. Při první návštěvě stránky byste měli vidět rozhraní zobrazení, jak je znázorněno na obrázku 5. Klikněte na tlačítko Zpracovat dodávku produktu. Stránka se vrátí zpět a teď byste měli vidět rozhraní pro vkládání, jak je znázorněno na obrázku 12. Kliknutím na tlačítka Přidat produkty ze zásilky nebo Zrušit se vrátíte do rozhraní zobrazení.

Poznámka

Při prohlížení rozhraní pro vkládání chvíli otestujte CompareValidators v textových polích s jednotkovou cenou. Po kliknutí na tlačítko Přidat produkty z dodávky s neplatnými hodnotami měny nebo cenami s hodnotou menší než nula by se měla zobrazit zpráva na straně klienta.

Po kliknutí na tlačítko Zpracovat dodávku produktu se zobrazí vložené rozhraní.

Obrázek 12: Po kliknutí na tlačítko Zpracovat dodávku produktu se zobrazí rozhraní pro vložení (kliknutím zobrazíte obrázek v plné velikosti).

Krok 4: Přidání produktů

Vše, co zbývá pro tento kurz, je uložit produkty do databáze v obslužné rutině události Přidat produkty z tlačítka Click dodávky. Toho lze dosáhnout vytvořením ProductsDataTable a přidáním ProductsRow instance pro každý z dodaných názvů produktů. Po přidání těchto ProductsRow s provedeme volání ProductsBLL metody třídy s UpdateWithTransaction , která předává metodu ProductsDataTable. Vzpomeňte si, že UpdateWithTransaction metoda, která byla vytvořena zpět v kurzu Obtékání úprav databáze v rámci transakce , předává ProductsDataTable metodu ProductsTableAdapter's UpdateWithTransaction . Odtud se spustí transakce ADO.NET a objekt TableAdapter vydá do databáze příkaz pro každou přidanou INSERTProductsRow do tabulky DataTable. Za předpokladu, že jsou všechny produkty přidány bez chyby, transakce je potvrzena, jinak je vrácena zpět.

Kód pro obslužnou rutinu události Add Products from Shipment Button s Click musí také provést kontrolu chyb. Vzhledem k tomu, že v rozhraní pro vkládání nejsou použity žádné RequiredFieldValidators, uživatel může zadat cenu produktu a vynechat jeho název. Vzhledem k tomu, že se vyžaduje název produktu, musíme v případě, že se taková podmínka rozvine, upozornit uživatele a nepokračovat v vložení. Úplný Click kód obslužné rutiny události následuje:

Protected Sub AddProducts_Click(sender As Object, e As EventArgs) _
    Handles AddProducts.Click
    ' Make sure that the UnitPrice CompareValidators report valid data...
    If Not Page.IsValid Then Exit Sub
    ' Add new ProductsRows to a ProductsDataTable...
    Dim products As New Northwind.ProductsDataTable()
    For i As Integer = firstControlID To lastControlID
        ' Read in the values for the product name and unit price
        Dim productName As String = CType(InsertingInterface.FindControl _
            ("ProductName" + i.ToString()), TextBox).Text.Trim()
        Dim unitPrice As String = CType(InsertingInterface.FindControl _
            ("UnitPrice" + i.ToString()), TextBox).Text.Trim()
        ' Ensure that if unitPrice has a value, so does productName
        If unitPrice.Length > 0 AndAlso productName.Length = 0 Then
            ' Display a warning and exit this event handler
            StatusLabel.Text = "If you provide a unit price you must also 
                                include the name of the product."
            StatusLabel.Visible = True
            Exit Sub
        End If
        ' Only add the product if a product name value is provided
        If productName.Length > 0 Then
            ' Add a new ProductsRow to the ProductsDataTable
            Dim newProduct As Northwind.ProductsRow = products.NewProductsRow()
            ' Assign the values from the web page
            newProduct.ProductName = productName
            newProduct.SupplierID = Convert.ToInt32(Suppliers.SelectedValue)
            newProduct.CategoryID = Convert.ToInt32(Categories.SelectedValue)
            If unitPrice.Length > 0 Then
                newProduct.UnitPrice = Convert.ToDecimal(unitPrice)
            End If
            ' Add any "default" values
            newProduct.Discontinued = False
            newProduct.UnitsOnOrder = 0
            products.AddProductsRow(newProduct)
        End If
    Next
    ' If we reach here, see if there were any products added
    If products.Count > 0 Then
        ' Add the new products to the database using a transaction
        Dim productsAPI As New ProductsBLL()
        productsAPI.UpdateWithTransaction(products)
        ' Rebind the data to the grid so that the products just added are displayed
        ProductsGrid.DataBind()
        ' Display a confirmation (don't use the Warning CSS class, though)
        StatusLabel.CssClass = String.Empty
        StatusLabel.Text = String.Format( _
            "{0} products from supplier {1} have been " & _
            "added and filed under category {2}.", _
            products.Count, Suppliers.SelectedItem.Text, Categories.SelectedItem.Text)
        StatusLabel.Visible = True
        ' Revert to the display interface
        ReturnToDisplayInterface()
    Else
        ' No products supplied!
        StatusLabel.Text = 
            "No products were added. Please enter the " & _
            "product names and unit prices in the textboxes."
        StatusLabel.Visible = True
    End If
End Sub

Obslužná rutina události začíná tím, že zajistí, aby Page.IsValid vlastnost vrátila hodnotu True. Pokud vrátí Falsehodnotu , znamená to, že jeden nebo více rutin CompareValidators hlásí neplatná data. V takovém případě se nechceme pokusit vložit zadané produkty nebo při pokusu o přiřazení hodnoty jednotkové ceny zadané uživatelem k vlastnosti s UnitPrice dojde k ProductsRow výjimce.

Dále se vytvoří nová ProductsDataTable instance (products). Smyčka For se používá k iteraci v textových polích s názvem produktu a jednotkovou cenou a Text vlastnosti se načtou do místních proměnných productName a unitPrice. Pokud uživatel zadal hodnotu pro jednotkovou cenu, ale ne pro odpovídající název produktu, StatusLabel zobrazí se zpráva Pokud zadáte jednotkovou cenu, musíte také zahrnout název produktu a obslužná rutina události se ukončí.

Pokud byl zadán název produktu, vytvoří se nová ProductsRow instance pomocí ProductsDataTable metody s NewProductsRow . Tato nová ProductsRow vlastnost instance s ProductName je nastavena na aktuální název produktu TextBox, zatímco SupplierID vlastnosti a CategoryID jsou přiřazeny SelectedValue vlastnosti DropDownLists v vložení rozhraní s hlavičky. Pokud uživatel zadal hodnotu pro cenu produktu, je přiřazena k ProductsRow vlastnosti instance s UnitPrice ; v opačném případě se vlastnost ponechá nepřiřazená, což způsobí NULL hodnotu pro UnitPrice v databázi. Discontinued Nakonec jsou vlastnosti a UnitsOnOrder přiřazeny pevně zakódovaným hodnotám False a 0 v uvedeném pořadí.

Po přiřazení vlastností k ProductsRow instanci se přidá do objektu ProductsDataTable.

Po dokončení smyčky For zkontrolujeme, jestli byly přidány nějaké produkty. Uživatel může koneckonců kliknout na Přidat produkty ze zásilky před zadáním názvů produktů nebo cen. Pokud existuje alespoň jeden produkt v ProductsDataTable, ProductsBLL je volána metoda třídy s UpdateWithTransaction . Dále se data vrátí do ProductsGrid GridView, takže nově přidané produkty se zobrazí v rozhraní zobrazení. se StatusLabel aktualizuje tak, aby se zobrazila potvrzovací zpráva, a ReturnToDisplayInterface vyvolá se , skryje rozhraní pro vkládání a zobrazí rozhraní pro zobrazení.

Pokud nebyly zadány žádné produkty, bude se zobrazovat rozhraní pro vkládání, ale zpráva Nebyly přidány žádné produkty. Do zobrazených textových polí zadejte názvy produktů a jednotkové ceny.

Obrázek 13, 14 a 15 znázorňuje rozhraní pro vkládání a zobrazení v akci. Na obrázku 13 uživatel zadal jednotkovou cenu bez odpovídajícího názvu produktu. Obrázek 14 znázorňuje rozhraní zobrazení po úspěšném přidání tří nových produktů, zatímco obrázek 15 znázorňuje dva z nově přidaných produktů v GridView (třetí je na předchozí stránce).

Při zadávání jednotkové ceny se vyžaduje název produktu.

Obrázek 13: Při zadávání jednotkové ceny se vyžaduje název produktu (kliknutím zobrazíte obrázek v plné velikosti)

Byly přidány tři nové zeleniny pro dodavatele Mayumi s

Obrázek 14: Byly přidány tři nové zeleniny pro dodavatele Mayumi s (kliknutím zobrazíte obrázek v plné velikosti)

Nové produkty najdete na poslední stránce GridView.

Obrázek 15: Nové produkty najdete na poslední stránce GridView (kliknutím zobrazíte obrázek v plné velikosti)

Poznámka

Logika dávkového vkládání použitá v tomto kurzu zabalí vložení do rozsahu transakce. Chcete-li to ověřit, záměrně zavete chybu na úrovni databáze. Například místo přiřazení nové ProductsRow instance s CategoryID vlastnost k vybrané hodnotě v rozevíracím Categories seznamu, přiřaďte ji k hodnotě jako i * 5. Tady i je indexer smyčky s hodnotami od 1 do 5. Proto při přidávání dvou nebo více produktů v dávce vložte první produkt platnou CategoryID hodnotu (5), ale následující produkty budou mít CategoryID hodnoty, které neodpovídají hodnotám CategoryID v Categories tabulce. Čistý efekt spočívá v tom, že zatímco první INSERT bude úspěšný, další selžou s porušením omezení cizího klíče. Vzhledem k tomu, že dávkové vložení je atomické, první INSERT se vrátí zpět a databáze se vrátí do stavu před zahájením procesu dávkového vložení.

Souhrn

V rámci tohoto a předchozích dvou kurzů jsme vytvořili rozhraní, která umožňují aktualizaci, odstranění a vložení dávek dat, z nichž všechny používaly podporu transakcí, které jsme přidali do vrstvy přístupu k datům v kurzu Zabalení úprav databáze v rámci transakce . V některých scénářích taková uživatelská rozhraní dávkového zpracování výrazně zlepšují efektivitu koncových uživatelů tím, že zpomalují počet kliknutí, zpětného volání a kontextových přepínačů typu klávesnice na myš a zároveň udržují integritu podkladových dat.

Tento kurz doplňuje náš pohled na práci s daty v dávkách. V další sadě kurzů se seznámíte s různými pokročilými scénáři vrstvy přístupu k datům, včetně použití uložených procedur v metodách TableAdapter, konfigurace nastavení na úrovni připojení a příkazů v dal, šifrování připojovacích řetězců a dalších!

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 S ren Jacob Lauritsen. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.