Dávkové vkládání (C#)
Zjistěte, jak v jedné operaci vložit více databázových záznamů. 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 zabalíme několik operací vložení v rámci transakce, abychom zajistili, že všechna vložení budou úspěšná nebo vrácená zpět.
Úvod
V kurzu Dávkové aktualizace jsme se podívali na přizpůsobení ovládacího prvku GridView tak, aby bylo možné upravit více záznamů. Uživatel, který stránku navštíví, může provést řadu změn a potom 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í ušetřit nespočet kliknutí a kontextových přepínačů mezi klávesami a myší 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í, aktualizací a odstraňování dat .
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. Například můžeme obdržet zásilku šesti různých produktů na čaj a kávu od společnosti Tokyo Traders. Pokud uživatel zadá šest produktů po jednom prostřednictvím ovládacího prvku DetailsView, bude muset zvolit mnoho stejných hodnot znovu a znovu: bude muset zvolit 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 je nejen časově náročné, ale také náchylné k chybám.
S trochou práce můžeme vytvořit rozhraní pro vkládání dávek, 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 jsou jeho ProductName
a UnitPrice
datovým polím přiřazeny 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.
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 nedělitelnost. Pusťme se do toho!
Krok 1: Vytvoření rozhraní zobrazení
Tento kurz se skládá z jedné stránky, která je rozdělená na dvě oblasti: oblast zobrazení a oblast pro vkládání. Rozhraní zobrazení, které vytvoříme v tomto kroku, zobrazuje produkty v zobrazení GridView a obsahuje tlačítko s názvem Zpracovat zásilku produktu. Po kliknutí na toto tlačítko se rozhraní pro 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 ze 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ž pouze jedno je viditelné najednou, je každé rozhraní obvykle umístěno v rámci webového ovládacího prvku Panel, 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ů na Designer (viz obrázek 2). Nastavte vlastnost Panel s ID
na DisplayInterface
. Při přidávání panelu do Designer jsou vlastnosti Height
a Width
nastaveny na 50px a 125px v uvedeném pořadí. Vymažte tyto hodnoty vlastností ze okno Vlastnosti.
Obrázek 2: Přetažení panelu z panelu 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 Tlačítka ID
na ProcessShipment
a její Text
vlastnost na Process Product Shipment (Zpracovat zásilku produktu). Nastavte vlastnost GridView na ID
ProductsGrid
a z její inteligentní značky vytvořte vazbu na nový objekt 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: Nastavte Drop-Down Seznamy na kartách UPDATE (UPDATE), INSERT a DELETE (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce ObjectDataSource přidá Visual Studio boundFields a CheckBoxField pro datová pole produktu. Odeberte všechna pole kromě ProductName
polí , CategoryName
SupplierName
, , UnitPrice
a Discontinued
. Nebojte se udělat jakékoli estetické přizpůsobení. Rozhodl(a) jsem se pole naformátovat UnitPrice
jako hodnotu měny, změnit pořadí polí a přejmenovat několik hodnot polí HeaderText
. Nakonfigurujte také 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 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 Button a GridView se zobrazí v rámci počáteční a uzavírací <asp:Panel>
značky. Vzhledem k tomu, že jsou tyto ovládací prvky v rámci panelu DisplayInterface
, můžeme je skrýt jednoduchým nastavením vlastnosti Panel na Visible
false
. Krok 3 se zabývá programovou změnou vlastnosti Panel s Visible
v reakci na kliknutí na tlačítko pro zobrazení jednoho rozhraní a skrytí druhého.
Podívejte se na průběh v prohlížeči. Jak je znázorněno na obrázku 5, mělo by se nad objektem GridView zobrazit tlačítko Zpracovat zásilku produktu, které obsahuje seznam produktů 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 produktů a ceny.
Začněte přetažením panelu z panelu nástrojů na Designer a jeho umístěním pod existující DisplayInterface
panel. ID
Nastavte vlastnost tohoto nově přidaného panelu na InsertingInterface
a nastavte jeho Visible
vlastnost na false
. V kroku 3 přidáme kód, který nastaví InsertingInterface
vlastnost Panel Visible
na true
. 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 na obrázku 1. Toto rozhraní lze vytvořit pomocí různých technik HTML, ale použijeme poměrně přímočarou: čtyřsloupovou 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, zdá se, že Designer je příliš ochotná style
vložit do značek nastavení bez přiřazení. Po vytvoření <table>
kódu 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 všechny webové ovládací prvky umístěné v rámci webového FindControl("controlID")
ovládacího prvku Tabulka jsou přístupné pouze pomocí vzoru . 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 databázových nebo uživatelem zadaných kritériích), protože webový ovládací prvek Tabulka 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>
Tento <table>
kód 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í, kde budou tlačítka Přidat produkty z dodávky a Zrušit; a střídavé BatchInsertRow
hodnoty a BatchInsertAlternatingRow
pro řádky, které budou obsahovat ovládací prvky TextBox produktu a jednotkové ceny. Vytvořil jsem odpovídající třídy CSS v Styles.css
souboru, aby se vkládání rozhraní vzhled podobný ovládacím prvkům GridView a DetailsView, které jsme použili v rámci těchto kurzů. Tyto třídy šablon stylů 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í. To <table>
by se mělo zobrazit jako sedmiřádková tabulka se čtyřmi sloupci v Designer, jak je znázorněno na obrázku 6.
Obrázek 6: Rozhraní pro vkládání se skládá z tabulky se čtyřmi sloupci 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, jednu pro dodavatele a jednu pro kategorii.
Nastavte vlastnost dropDownList dodavatele ID
na Suppliers
a vytvořte vazbu s novým objektem ObjectDataSource s názvem SuppliersDataSource
. Nakonfigurujte nový objekt ObjectDataSource tak, aby načítal data z SuppliersBLL
metody třídy s GetSuppliers
, a nastavte rozevírací seznam UPDATE tab s na hodnotu (None). Dokončete průvodce kliknutím na Dokončit.
Obrázek 7: Konfigurace objektu ObjectDataSource pro použití SuppliersBLL
metody 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 s.
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ý dropDownList Categories
a vytvořte vazbu na nový objekt 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 void ProcessShipment_Click(object sender, EventArgs e)
{
DisplayInterface.Visible = false;
InsertingInterface.Visible = true;
}
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 void AddProducts_Click(object sender, EventArgs e)
{
// TODO: Save the products
// Revert to the display interface
ReturnToDisplayInterface();
}
protected void CancelButton_Click(object sender, EventArgs e)
{
// Revert to the display interface
ReturnToDisplayInterface();
}
const int firstControlID = 1;
const int lastControlID = 5;
private void ReturnToDisplayInterface()
{
// Reset the control values in the inserting interface
Suppliers.SelectedIndex = 0;
Categories.SelectedIndex = 0;
for (int i = firstControlID; i <= lastControlID; i++)
{
((TextBox)InsertingInterface.FindControl("ProductName" + i.ToString())).Text =
string.Empty;
((TextBox)InsertingInterface.FindControl("UnitPrice" + i.ToString())).Text =
string.Empty;
}
DisplayInterface.Visible = true;
InsertingInterface.Visible = false;
}
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 UpdateWithTransaction
si, že metoda, která byla vytvořena zpět v kurzu Obtékání změn databáze v rámci transakce , předává metodu ProductsDataTable
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 void AddProducts_Click(object sender, EventArgs e)
{
// Make sure that the UnitPrice CompareValidators report valid data...
if (!Page.IsValid)
return;
// Add new ProductsRows to a ProductsDataTable...
Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();
for (int i = firstControlID; i <= lastControlID; i++)
{
// Read in the values for the product name and unit price
string productName = ((TextBox)InsertingInterface.FindControl
("ProductName" + i.ToString())).Text.Trim();
string unitPrice = ((TextBox)InsertingInterface.FindControl
("UnitPrice" + i.ToString())).Text.Trim();
// Ensure that if unitPrice has a value, so does productName
if (unitPrice.Length > 0 && productName.Length == 0)
{
// 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;
return;
}
// Only add the product if a product name value is provided
if (productName.Length > 0)
{
// Add a new ProductsRow to the ProductsDataTable
Northwind.ProductsRow newProduct = 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)
newProduct.UnitPrice = Convert.ToDecimal(unitPrice);
// Add any "default" values
newProduct.Discontinued = false;
newProduct.UnitsOnOrder = 0;
products.AddProductsRow(newProduct);
}
}
// If we reach here, see if there were any products added
if (products.Count > 0)
{
// Add the new products to the database using a transaction
ProductsBLL productsAPI = 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;
}
}
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 objektu ProductsGrid
GridView, aby se nově přidané produkty zobrazily v rozhraní pro zobrazení. Aktualizuje StatusLabel
se tak, aby se zobrazila potvrzovací zpráva, a ReturnToDisplayInterface
vyvolá se. Skryje se rozhraní pro vložení a zobrazí se rozhraní pro zobrazení.
Pokud nebyly zadány žádné produkty, rozhraní pro vkládání zůstane zobrazené, 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 nově přidané produkty 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é zelenina 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í vlastnosti nové ProductsRow
instance s CategoryID
vybrané hodnotě v rozevíracím Categories
seznamu ji přiřaďte k hodnotě, jako je i * 5
. Tady i
je indexer smyčky a obsahuje hodnoty v rozsahu od 1 do 5. Proto při přidávání dvou nebo více produktů v dávce vložte první produkt bude mít 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 vrátí databázi do stavu před zahájením procesu dávkového vložení.
Souhrn
V tomto a předchozích dvou kurzech jsme vytvořili rozhraní, která umožňují aktualizovat, odstraňovat a vkládat dávky dat, přičemž všechny využívají podporu transakcí, kterou jsme přidali do vrstvy přístupu k datům v kurzu Obtékání úprav databáze v rámci transakce . V některých scénářích takové dávkové zpracování uživatelských rozhraní výrazně vylepšuje efektivitu koncových uživatelů tím, že snižuje počet kliknutí, zpětného volání a kontextových přepínačů pomocí klávesnice na myš a současně zachovává integritu podkladových dat.
Tento kurz doplňuje náš pohled na práci s daty v dávkách. Další sada kurzů prozkoumá 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 s, konfigurace nastavení na úrovni připojení a příkazů v dal, šifrování připojovacích řetězců a dalších!
Šťastné 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 najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty tohoto kurzu byly Hilton Giesenow a S ren Jacob Lauritsen. Chcete si projít moje nadcházející články na WEBU MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.comadresu .