Dávkové vkládání (VB)
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í.
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.
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.
Obrázek 3: Zobrazení dat vrácených metodou ProductsBLL
třídy GetProducts
(kliknutím zobrazíte obrázek v plné velikosti)
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ě ProductName
polí , CategoryName
SupplierName
, , UnitPrice
a 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.
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.
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.
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.
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.
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
, UnitPrice2
ProductName3
, , UnitPrice3
atd.
Přidejte CompareValidator za každé pole textových polí jednotkové ceny a nastavte ControlToValidate
vlastnost na odpovídající ID
hodnotu . 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 True
ShowSummary
False
.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.
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 false
hodnotu .
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.
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 False
hodnotu . 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 ReturnToDisplayInterface
metodu, kterou na chvíli přidáme. Kromě skrytí panelu InsertingInterface
a zobrazení panelu DisplayInterface
ReturnToDisplayInterface
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.
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 INSERT
ProductsRow
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í False
hodnotu , 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).
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)
Obrázek 14: Byly přidány tři nové zeleniny pro dodavatele Mayumi s (kliknutím zobrazíte obrázek v plné velikosti)
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.