Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Zjistěte, jak do jedné operace vložit více záznamů databáze. Ve vrstvě uživatelského rozhraní rozšiřujeme Objekt GridView tak, aby uživatel mohl zadat více nových záznamů. Ve vrstvě přístupu k datům obalujeme několik vložek v rámci transakce, aby bylo zajištěno, že všechny vložky úspěšně proběhnou nebo budou všechny vráceny zpět.
Úvod
V kurzu Dávkové aktualizace jsme se zaměřili na úpravu ovládacího prvku GridView tak, aby rozhraní umožňovalo editaci více záznamů. Uživatel, který stránku navštíví, může provést řadu změn a pak jediným kliknutím na tlačítko provést dávkovou aktualizaci. V situacích, kdy uživatelé často aktualizují mnoho záznamů na jednom místě, může takové rozhraní ušetřit bezpočet kliknutí a přepínačů kontextu myši na myš ve srovnání s výchozími funkcemi úprav pro jednotlivé řádky, které byly poprvé prozkoumány v kurzu Přehled vkládání, aktualizace a odstraňování dat .
Tento koncept lze použít také při přidávání záznamů. Představte si, že zde v Northwind Traders obvykle dostáváme zásilky od dodavatelů, kteří obsahují řadu produktů pro určitou kategorii. Jako příklad můžeme obdržet dodávku šesti různých produktů čaje a kávy od společnosti Tokyo Traders. Pokud uživatel zadá šest produktů postupně prostřednictvím ovládacího prvku DetailsView, bude muset vybrat mnoho stejných hodnot znovu: bude muset vybrat stejnou kategorii (nápoje), stejného dodavatele (Tokyo Traders), stejnou ukončenou hodnotu (False) a stejné jednotky pro hodnotu objednávky (0). Toto opakované zadávání dat není jenom časově náročné, ale náchylné k chybám.
S trochou práce můžeme vytvořit dávkové vkládání rozhraní, které uživateli umožňuje vybrat dodavatele a kategorii jednou, zadat řadu názvů produktů a jednotkových cen a poté 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 jsou jeho ProductName
a UnitPrice
datová pole přiřazena hodnotám zadaným v textových polích, zatímco jeho CategoryID
a SupplierID
hodnoty 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, respektive.
Obrázek 1: Rozhraní dávkového vkládání (kliknutím zobrazíte obrázek s plnou velikostí)
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 tutoriálech zabalíme vložení do rozsahu transakce, abychom zajistili atomicitu. Pojďme začít!
Krok 1: Vytvoření rozhraní pro zobrazení
Tento kurz se skládá z jedné stránky rozdělené do dvou oblastí: oblasti zobrazení a oblasti vložení. Rozhraní pro zobrazení, které vytvoříme v tomto kroku, zobrazuje produkty v GridView a obsahuje tlačítko s názvem Zpracovat zásilku produktu. Po kliknutí na toto tlačítko se rozhraní pro zobrazení nahradí vloženým rozhraním, které je znázorněno na obrázku 1. Rozhraní zobrazení se vrátí po kliknutí na tlačítko Přidat produkty z dodávky nebo Zrušit. V kroku 2 vytvoříme vložené rozhraní.
Při vytváření stránky se dvěma rozhraními je vždy viditelné pouze jedno z nich, obvykle se každé rozhraní umístí do webového ovládacího prvku Panel, který slouží jako kontejner pro jiné ovládací prvky. Naše stránka proto bude mít dva ovládací prvky panelu jeden pro každé rozhraní.
Začněte otevřením BatchInsert.aspx
stránky ve BatchData
složce a přetažením panelu z panelu nástrojů do Návrháře (viz obrázek 2). Nastavte vlastnost panelu s ID
na DisplayInterface
hodnotu. Při přidávání panelu do Návrháře jsou jeho Height
a Width
vlastnosti nastaveny na 50px a 125px v uvedeném pořadí. Vymažte tyto hodnoty vlastností z okna Vlastnosti.
Obrázek 2: Přetažení panelu z panelu nástrojů do Návrháře (kliknutím zobrazíte obrázek v plné velikosti)
Poté přetáhněte ovládací prvek Button a GridView do panelu. Nastavte vlastnost tlačítka ID
na ProcessShipment
a jeho vlastnost Text
na Zpracování dodávky produktu. Nastavte vlastnost GridView ID
na ProductsGrid
a ze smart tagu ji navázejte na nový ObjectDataSource pojmenovaný ProductsDataSource
. Nakonfigurujte ObjectDataSource tak, aby získával data z metody třídy ProductsBLL
GetProducts
. Vzhledem k tomu, že tento Objekt GridView slouží pouze k zobrazení dat, nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné). Kliknutím na tlačítko 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 seznamů na kartách UPDATE, INSERT a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce nástrojem ObjectDataSource Visual Studio přidá BoundFields a CheckBoxField pro pole dat produktu. Odeberte všechna pole kromě ProductName
, CategoryName
, SupplierName
, UnitPrice
a Discontinued
. Nebojte se udělat 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.
Po přidání ovládacích prvků Panel, Button, GridView a ObjectDataSource a přizpůsobení polí GridView by mělo deklarativní značkování stránky vypadat 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 tlačítko a objekt GridView se zobrazují v rámci počátečních a uzavíracích <asp:Panel>
značek. Vzhledem k tomu, že tyto ovládací prvky jsou v panelu DisplayInterface
, můžeme je skrýt jednoduše nastavením vlastnosti Panel na Visible
False
. Krok 3 se zabývá programovou změnou vlastnosti panelu Visible
v reakci na kliknutí na tlačítko zobrazit jedno rozhraní při skrytí druhé.
Chvilku si prohlédněte průběh v prohlížeči. Jak je znázorněno na obrázku 5, měli byste vidět tlačítko pro zpracování zásilky produktu umístěné nad GridView, který zobrazuje seznam produktů po deseti.
Obrázek 5: Zobrazení seznamů produktů a nabídek řazení a stránkování (kliknutím zobrazíte obrázek v plné velikosti)
Krok 2: Vytvoření rozhraní pro vložení
Po dokončení rozhraní pro zobrazení jsme připraveni vytvořit vložené rozhraní. Pro účely tohoto kurzu vytvoříme vložené rozhraní, 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 cenových hodnot. S tímto rozhraním může uživatel přidat jeden do pěti nových produktů, které sdílejí stejnou kategorii a dodavatele, ale mají jedinečné názvy produktů a ceny.
Začněte přetažením panelu z panelu nástrojů do Návrháře a umístěním panelu pod existující DisplayInterface
panel.
ID
Nastavte vlastnost tohoto nově přidaného panelu InsertingInterface
a nastavte jeho Visible
vlastnost na False
. V kroku 3 přidáme kód, který nastaví InsertingInterface
vlastnost Visible
u True
Panelu. Vymažte také hodnoty vlastností panelu Height
a Width
.
Dále musíme vytvořit rozhraní pro vkládání, které se zobrazilo u obrázku 1. Toto rozhraní lze vytvořit prostřednictvím různých technik HTML, ale my použijeme poměrně jednoduchou tabulku: čtyřsloupce sedmiřádkové tabulky.
Poznámka:
Při zadávání kódu pro elementy HTML <table>
dávám přednost použití zobrazení Zdroj. Visual Studio sice obsahuje nástroje pro přidávání <table>
prvků prostřednictvím Návrháře, ale zdá se, že Návrhář je příliš ochotný vložit do kódu nezaškrtnutá style
nastavení. Po vytvoření <table>
značkování se obvykle vrátím do Návrháře, abych přidal Webové ovládací prvky a nastavil 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, nikoli webového ovládacího prvku Table Web, protože k webovým ovládacím prvkům nadřazeným tabulce lze přistupovat pouze pomocí vzoru FindControl("controlID")
. Používám však webové ovládací prvky tabulky pro tabulky s dynamickou velikostí (ty, jejichž řádky nebo sloupce jsou založeny na některých kritériích databáze nebo uživatelem), protože ovládací prvek Table Web lze vytvořit programově.
Zadejte následující značky uvnitř tagů <asp:Panel>
panelu InsertingInterface
:
<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>
Tento <table>
kód zatím neobsahuje žádné webové ovládací prvky. Tyto ovládací prvky přidáme prozatím. Všimněte si, že každý <tr>
prvek obsahuje konkrétní nastavení třídy CSS: BatchInsertHeaderRow
pro řádek záhlaví, kam bude umístěn dodavatel a kategorie DropDownLists; BatchInsertFooterRow
pro řádek zápatí, kde budou tlačítka Přidat produkty z dodávky a Zrušit umístěna; a hodnoty střídají BatchInsertRow
a BatchInsertAlternatingRow
pro řádky, které budou obsahovat produktové a cenové TextBoxy. Vytvořil jsem odpovídající třídy CSS v Styles.css
souboru, aby rozhraní pro vkládání mělo vzhled podobný ovládacím prvkům GridView a DetailsView, které jsme používali v těchto kurzech. Tyto třídy CSS jsou uvedeny 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í. To <table>
by se mělo v Návrháři zobrazit jako tabulka se čtyřmi sloupci se sedmi řádky, jak znázorňuje obrázek 6.
Obrázek 6: Vložené rozhraní se skládá ze čtyřsloupce Seven-Row tabulky (kliknutím zobrazíte obrázek v plné velikosti).
Teď jsme připraveni přidat webové ovládací prvky do rozhraní pro vložení. Přetáhněte dva rozevírací seznamy ze sady nástrojů do příslušných buněk v tabulce jedna pro dodavatele a jednu pro kategorii.
Nastavte vlastnost DropDownList ID
dodavatele na Suppliers
a vytvořte vazbu na nový ObjectDataSource s názvem SuppliersDataSource
. Nakonfigurujte nový ObjectDataSource tak, aby načetl data z metody třídy SuppliersBLL
a nastavte rozevírací seznam karty UPDATE na (None). Kliknutím na tlačítko Dokončit dokončete průvodce.
Obrázek 7: Konfigurace ObjectDataSource pro použití SuppliersBLL
metody třídy GetSuppliers
(kliknutím zobrazíte obrázek v plné velikosti)
Nechejte rozevírací seznam zobrazit Suppliers
datové pole a použít CompanyName
datové pole pro jeho hodnoty SupplierID
.
Obrázek 8: Zobrazení datového CompanyName
pole a použití SupplierID
jako hodnoty (kliknutím zobrazíte obrázek s plnou velikostí)
Pojmenujte druhý DropDownList Categories
a vytvořte vazbu na nový ObjectDataSource s názvem CategoriesDataSource
.
CategoriesDataSource
Nakonfigurujte ObjectDataSource tak, aby používal metodu CategoriesBLL
třídy GetCategories
; nastavte rozevírací seznamy na kartách UPDATE a DELETE na (None) a klikněte na Dokončit pro dokončení průvodce. Nakonec nechte DropDownList zobrazovat datové pole CategoryName
a použít CategoryID
jako hodnotu.
Po přidání těchto dvou rozevíracích seznamů a vázaných na správně nakonfigurované objekty ObjectDataSources by obrazovka měla vypadat podobně jako na obrázku 9.
Obrázek 9: Řádek záhlaví teď obsahuje Suppliers
a Categories
rozevírací seznamy (kliknutím zobrazíte obrázek v plné velikosti).
Teď potřebujeme 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ů do Návrháře pro každý z pěti názvů produktů a cenových řádků.
ID
Nastavte vlastnosti textových polí na ProductName1
, UnitPrice1
, ProductName2
, UnitPrice2
, ProductName3
, UnitPrice3
, atd.
Přidejte CompareValidator ke každému textovému poli s jednotkovou cenou a nastavte vlastnost ControlToValidate
na odpovídající ID
. Nastavte také vlastnost Operator
na hodnotu GreaterThanEqual
, ValueToCompare
na hodnotu 0 a Type
na hodnotu Currency
. Tato nastavení instruují CompareValidator, aby zajistil, že je cena, pokud je zadaná, platná hodnota měny, která je větší nebo rovna nule.
Text
Nastavte vlastnost *a ErrorMessage
na hodnotu Cena musí být větší nebo rovna nule. Také prosím vynechte jakékoli 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 mohl zadat až pět produktů. Pokud například uživatel zadal název produktu a jednotkovou cenu pro první tři řádky, ponechali jsme poslední dva řádky prázdné, stačí do systému přidat tři nové produkty. Vzhledem k tomu, že ProductName
je potřebný, budeme muset programově zkontrolovat, zda je zadána jednotková cena a odpovídající hodnota názvu produktu. Tuto kontrolu vyřešíme 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 symbol $ před každé textové pole pro zadání jednotkové ceny, které slouží jako vizuální pomůcka poučující uživatele, aby při zadávání ceny vynechal symbol měny.
Nakonec přidejte do panelu InsertingInterface
ovládací prvek ValidationSummary, nastavte jeho vlastnost ShowMessageBox
na True
a jeho vlastnost ShowSummary
na False
. Pokud uživatel zadá neplatnou hodnotu jednotkové ceny, zobrazí se hvězdička vedle problematických ovládacích prvků TextBox a ValidationSummary zobrazí chybové okno na straně klienta s chybovou zprávou, kterou jsme určili dříve.
V tomto okamžiku by obrazovka měla vypadat podobně jako na obrázku 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 tlačítka z panelu nástrojů do zápatí rozhraní pro vkládání, nastavte vlastnosti tlačítek na ID
a AddProducts
a vlastnosti na CancelButton
a Text
pro přidání produktů z dodávky a zrušení. Kromě toho nastavte CancelButton
atribut ovládacího prvku CausesValidation
na false
.
Nakonec musíme přidat ovládací prvek Label Web, který zobrazí stavové zprávy pro obě rozhraní. Když například uživatel úspěšně přidá novou zásilku produktů, chceme se vrátit do rozhraní pro zobrazení a zobrazit potvrzovací zprávu. Pokud však uživatel poskytne cenu nového produktu, ale ponechá název produktu, musíme zobrazit zprávu s upozorněním, protože ProductName
pole je povinné. Vzhledem k tomu, že potřebujeme, aby se tato zpráva zobrazovala pro obě rozhraní, umístěte ji v horní části stránky mimo panely.
Přetáhněte ovládací prvek popisek Web z panelu nástrojů do horní části stránky v návrháři.
ID
Nastavte vlastnost na StatusLabel
, vymažte Text
vlastnost a nastavte vlastnosti Visible
EnableViewState
na False
. Jak jsme viděli v předchozích kurzech, nastavení vlastnosti EnableViewState
na False
nám umožňuje programově měnit hodnoty vlastností štítků a nechat je automaticky vrátit se k výchozím hodnotám při následném zpětném odeslání. To zjednodušuje kód pro zobrazení stavové zprávy v reakci na nějakou akci uživatele, která zmizí v následném zpětném odeslání. Nakonec nastavte vlastnost ovládacího prvku StatusLabel
na Warning, což je název třídy CSS definované v CssClass
, která zobrazuje text ve velkém, kurzívě, tučném, červeném písmu.
Obrázek 11 znázorňuje Designer Visual Studio po přidání a konfiguraci štítku.
Obrázek 11: Umístěte StatusLabel
ovládací prvek nad dva ovládací prvky panelu (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 tuto chvíli jsme dokončili revize pro naše rozhraní pro zobrazení a vkládání, ale stále jsme zůstali se dvěma úkoly:
- Přepínání mezi rozhraními pro zobrazení a vkládání
- Přidání produktů do zásilky do databáze
V současné době je rozhraní zobrazení viditelné, ale vložené rozhraní je skryté. Důvodem je, že vlastnost panelu DisplayInterface
Panel Visible
je nastavena na True
(výchozí hodnota), zatímco vlastnost panelu InsertingInterface
Panel Visible
je nastavena na False
. Abychom mohli přepínat mezi dvěma rozhraními, stačí přepnout každou hodnotu vlastnosti ovládacího prvku Visible
.
Chceme přejít z rozhraní pro zobrazení do rozhraní pro vložení, když kliknete na tlačítko Zpracovat dodávku produktu. 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 v rozhraní pro vložení vytvořte obslužné rutiny událostí pro ovládací prvky Add Products from Shipment (Přidat produkty z dodávky) a Cancel Button (Tlačítko Zrušit). Když kliknete na některé z těchto tlačítek, musíme se vrátit zpět k rozhraní pro zobrazení. Vytvořte Click
obslužné rutiny událostí pro oba tlačítkové ovládací prvky tak, aby volaly ReturnToDisplayInterface
, metodu, kterou přidáme za chvíli. Kromě skrytí panelu InsertingInterface
a zobrazení panelu DisplayInterface
ReturnToDisplayInterface
musí metoda vrátit webové ovládací prvky do stavu před úpravou. To zahrnuje nastavení vlastnosti DropDownLists SelectedIndex
na hodnotu 0 a vymazání Text
vlastností ovládacích prvků TextBox.
Poznámka:
Než se vrátíme do rozhraní pro zobrazení, zvažte, co se může stát, když jsme ovládací prvky nevrátili do stavu před úpravou. Uživatel může kliknout na tlačítko Zpracovat zásilku produktu, zadat produkty z dodávky a potom kliknout na Přidat produkty z dodávky. Tím přidáte produkty a vrátíte 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 rozbalovacího seznamu a hodnoty textového pole budou stále obsahovat jejich předchozí hodnoty.
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
, přičemž se ve čtvrtém kroku vrátíme k obslužné rutině události Přidat produkty z zásilky Click
a přidáme kód pro uložení produktů.
ReturnToDisplayInterface
začíná vrácením rozevíracích seznamů Suppliers
a Categories
k jejich prvním možnostem. Dvě konstanty firstControlID
a lastControlID
označí hodnoty indexu počátečního a koncového For
ovládacího prvku použité při pojmenování názvu produktu a textových polí jednotkové ceny v rozhraní pro vložení a používají se v mezích smyčky, která nastaví Text
vlastnosti ovládacích prvků TextBox zpět na prázdný řetězec. Nakonec se vlastnosti panelů Visible
resetují, aby bylo rozhraní pro vkládání skryto a rozhraní pro zobrazení viditelné.
Chvíli vyzkoušejte tuto stránku 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 zásilku produktu. Stránka se obnoví a teď byste měli vidět vkládací rozhraní, jak je znázorněno na obrázku 12. Kliknutím na tlačítko Přidat produkty z dodávky nebo Zrušit se vrátíte do rozhraní pro zobrazení.
Poznámka:
Při prohlížení rozhraní pro vložení si najděte chvíli na otestování CompareValidators v textových polích určených pro jednotkové ceny. Když kliknete na tlačítko Přidat produkty z dodávky s neplatnými hodnotami měny nebo cenami menšími než nula, mělo by se zobrazit výstražné hlášení na straně klienta.
Obrázek 12: Po kliknutí na tlačítko Zpracování dodávky 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 tutoriál, je uložit produkty do databáze v obslužné rutině události Přidat produkty z tlačítka zásilky Click
. Toho lze dosáhnout vytvořením ProductsDataTable
a přidáním ProductsRow
instance pro každý zadaný název produktu. Po přidání těchto ProductsRow
objektů provedeme volání ProductsBLL
metody třídy s UpdateWithTransaction
předáváním ProductsDataTable
. Vzpomeňte si, že UpdateWithTransaction
metoda, která byla vytvořena v tutoriálu Zabalování úprav databáze v rámci transakce, předá ProductsDataTable
k metodě ProductsTableAdapter
objektu UpdateWithTransaction
. Odtud se spustí ADO.NET transakce a TableAdapter vydá INSERT
příkaz do databáze pro každý přidaný ProductsRow
v DataTable. Za předpokladu, že všechny produkty jsou přidány bez chyby, transakce je potvrzena, jinak se vrátí zpět.
Kód obslužné rutiny události Přidat produkty z tlačítka Click
zásilky 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 při vynechání jeho názvu. Vzhledem k tomu, že název produktu je povinný, pokud nastane taková podmínka, musíme uživatele upozornit a nepokračovat ve vkládání záznamů. Kompletní kód obslužné rutiny události Click
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á zajištěním, že Page.IsValid
vlastnost vrací hodnotu True
. Pokud se vrátí False
, znamená to, že jeden nebo více porovnávačů hlásí neplatná data. V takovém případě se nechceme pokoušet vložit zadané produkty, protože bychom skončili s výjimkou při pokusu o přiřazení hodnoty jednotkové ceny zadané uživatelem ke vlastnosti ProductsRow
.
Dále se vytvoří nová ProductsDataTable
instance (products
). Smyčka For
se používá k iteraci přes textová pole názvu produktu a jednotkové ceny, přičemž vlastnosti Text
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, zobrazí se zpráva Pokud zadáte jednotkovou cenu, StatusLabel
musíte zahrnout také 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á instanční vlastnost ProductsRow
je vlastnost ProductName
nastavena na TextBox aktuálního názvu produktu, zatímco vlastnosti SupplierID
a CategoryID
jsou přiřazeny vlastnostem SelectedValue
rozbalovacích seznamů v hlavičce rozhraní pro vkládání. Pokud uživatel zadal hodnotu pro cenu produktu, je přiřazena k vlastnosti instance ProductsRow
UnitPrice
; jinak zůstane vlastnost nepřiřazená, což bude mít za následek hodnotu NULL
pro UnitPrice
v databázi.
Discontinued
UnitsOnOrder
Nakonec jsou vlastnosti přiřazeny pevně zakódovaným hodnotám False
a 0.
Po přiřazení vlastností k ProductsRow
instanci je přidán do objektu ProductsDataTable
.
Po dokončení smyčky For
zkontrolujeme, jestli byly přidány nějaké produkty. Uživatel může po všem kliknout na položku Přidat produkty z dodávky před zadáním jakýchkoli názvů produktů nebo cen. Pokud je v ProductsDataTable
alespoň jeden produkt, je volána metoda třídy ProductsBLL
s UpdateWithTransaction
. V dalším kroku se data převedou do objektu ProductsGrid
GridView, aby se nově přidané produkty zobrazily v rozhraní zobrazení. Aktualizuje se StatusLabel
tak, aby zobrazila potvrzovací zprávu, a ReturnToDisplayInterface
se vyvolá, čímž se skryje rozhraní pro vkládání a zobrazí se rozhraní pro zobrazení.
Pokud nebyly zadány žádné produkty, rozhraní pro vkládání zůstane zobrazeno, ale zpráva Nebyly přidány žádné produkty. Do textových polí zadejte názvy produktů a ceny jednotek.
Obrázek 13, 14 a 15 znázorňují rozhraní vložení a zobrazení v akci. Na obrázku 13 uživatel zadal jednotkovou cenu bez odpovídajícího názvu produktu. Obrázek 14 ukazuje rozhraní pro zobrazení po úspěšném přidání tří nových produktů, zatímco obrázek 15 ukazuje dva nově přidané produkty v GridView (třetí je na předchozí stránce).
Obrázek 13: Při zadávání jednotkové ceny je požadován název produktu (kliknutím zobrazíte obrázek v plné velikosti).
Obrázek 14: Byly přidány tři novéggy pro dodavatele Mayumi s (kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 15: Nové produkty najdete na poslední stránce objektu GridView (kliknutím zobrazíte obrázek v plné velikosti).
Poznámka:
Logika dávkového vkládání použitá v tomto kurzu obklopuje vložení uvnitř rozsahu transakce. Chcete-li to ověřit, účelně zavést chybu na úrovni databáze. Například místo přiřazení vlastnosti ProductsRow
nové CategoryID
instance k vybrané hodnotě v rozevíracím seznamu Categories
, přiřaďte ji k hodnotě, jakou je i * 5
. Tady i
je indexer smyčky a má hodnoty v rozsahu od 1 do 5. Proto při hromadném vložení dvou nebo více produktů bude mít první produkt platnou CategoryID
hodnotu (5), ale následné produkty budou mít odlišné CategoryID
hodnoty, které neodpovídají CategoryID
hodnotám v Categories
tabulce. Výsledkem je, že zatímco první INSERT
bude úspěšný, následné selžou kvůli porušení omezení cizího klíče. Vzhledem k tomu, že dávkové vložení je atomické, první INSERT
se vrátí zpět a vrátí databázi do jejího stavu před zahájením procesu dávkového vložení.
Shrnutí
Během tohoto a předchozích dvou kurzů jsme vytvořili rozhraní, která umožňují aktualizovat, odstraňovat a vkládat dávky dat, přičemž všechna tato rozhraní používala podporu transakcí, kterou jsme přidali do vrstvy přístupu k datům v kurzu Zapouzdření úprav databáze v rámci transakce. V některých scénářích tato uživatelská rozhraní dávkového zpracování výrazně zlepšují efektivitu koncových uživatelů snížením počtu kliknutí, postbacků a přepínačů kontextu mezi klávesami a myší a zároveň zachováním integrity podkladových dat.
V tomto kurzu se podíváme na práci s dávkovými daty. Další sada kurzů zkoumá celou řadu pokročilých scénářů 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ší!
Šťastné programování!
O autorovi
Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Naučte se sami ASP.NET 2.0 za 24 hodin. Může být dosažitelný na mitchell@4GuysFromRolla.comadrese .
Zvláštní díky
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí hodnotitelé tohoto tutoriálu byli Hilton Giesenow a Søren Jacob Lauritsen. Chcete si projít nadcházející články MSDN? Pokud ano, napište mi zprávu na mitchell@4GuysFromRolla.com.