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 aktualizovat více záznamů databáze v jedné operaci. Ve vrstvě uživatelského rozhraní vytvoříme GridView, kde je každý řádek upravitelný. Ve vrstvě přístupu k datům zabalíme více operací aktualizace v rámci transakce, aby se zajistilo, že všechny aktualizace budou úspěšné nebo všechny aktualizace se vrátí zpět.
Úvod
V předchozím kurzu jsme zjistili, jak rozšířit vrstvu přístupu k datům o přidání podpory databázových transakcí. Databázové transakce zaručují, že řada příkazů pro úpravu dat bude považována za jednu atomické operace, která zajistí, že všechny úpravy selžou nebo všechny budou úspěšné. Nyní, když máme nízkoúrovňové funkce DAL za sebou, jsme připraveni zaměřit se na vytváření rozhraní pro úpravy dávkových dat.
V tomto kurzu vytvoříme GridView, kde je každý řádek upravitelný (viz obrázek 1). Vzhledem k tomu, že se každý řádek vykresluje v rozhraní pro úpravy, není nutné používat sloupce tlačítek Upravit, Aktualizovat a Zrušit. Místo toho jsou na stránce dvě tlačítka Update Products, která po kliknutí vyčíslí řádky GridView a aktualizují databázi.
Obrázek 1: Každý řádek v objektu GridView je upravitelný (kliknutím zobrazíte obrázek s plnou velikostí)
Pojďme začít!
Poznámka:
V kurzu Provádění dávkových aktualizací jsme vytvořili rozhraní dávkové úpravy pomocí ovládacího prvku DataList. Tento tutoriál se liší od předchozího v tom, že používá GridView a dávková aktualizace se provádí v rámci rozsahu transakce. Po dokončení tohoto kurzu doporučuji, abyste se vrátili do předchozího kurzu a aktualizovali ji tak, aby používala funkce související s transakcemi databáze přidané v předchozím kurzu.
Prozkoumání kroků pro úpravu všech řádků GridView
Jak je popsáno v kurzu Vložení, aktualizace a odstranění dat , gridView nabízí integrovanou podporu pro úpravy podkladových dat na jednotlivé řádky. GridView interně zaznamená, jaký řádek je možné upravovat prostřednictvím jeho EditIndex vlastnosti. Vzhledem k tomu, že Objekt GridView je svázán s jeho zdrojem dat, kontroluje každý řádek, aby zjistil, jestli se index řádku rovná hodnotě EditIndex. Pokud ano, pole řádků se vykreslují pomocí jejich rozhraní pro úpravy. Pro BoundField je rozhraní pro úpravy TextBox, jehož vlastnost Text je nastavena na hodnotu datového pole určeného vlastností DataField tohoto BoundField. Pro TemplateFields se EditItemTemplate používá místo ItemTemplate.
Vzpomeňte si, že pracovní postup úprav začíná, když uživatel klikne na tlačítko Upravit řádek. To způsobí postback, nastaví vlastnost GridView na index kliknutého řádku a znovu naváže data do tabulky. Po kliknutí na tlačítko Storno řádku je při zpětném EditIndex vrácení nastavena hodnota -1 před opětovnou vazbou dat do mřížky. Vzhledem k tomu, že řádky GridView začínají indexovat na nulu, nastavení EditIndex na -1 způsobí zobrazení GridView v režimu jen pro čtení.
Vlastnost EditIndex funguje dobře pro úpravy jednotlivých řádků, ale není určená pro dávkové úpravy. Abychom mohli upravit celý Objekt GridView, musíme mít každý řádek vykreslený pomocí jeho rozhraní pro úpravy. Nejjednodušším způsobem, jak toho dosáhnout, je vytvořit rozhraní, kde je každé upravitelné pole implementováno jako TemplateField s jeho rozhraním pro úpravy definovaným v ItemTemplate.
V dalších několika krocích vytvoříme zcela upravitelný Objekt GridView. V kroku 1 začneme vytvořením objektu GridView a jeho ObjectDataSource a převodem jeho BoundField a CheckBoxField na TemplateFields. V krocích 2 a 3 přesuneme rozhraní pro úpravy z TemplateFields EditItemTemplate na jejich ItemTemplate rozhraní.
Krok 1: Zobrazení informací o produktu
Než se budeme starat o vytvoření objektu GridView, kde jsou řádky upravitelné, začněme jednoduchým zobrazením informací o produktu.
BatchUpdate.aspx Otevřete stránku ve BatchData složce a přetáhněte Objekt GridView ze sady nástrojů do Návrháře. Nastavte Objekt GridView na IDProductsGrid a z jeho inteligentní značky zvolte, že se má svázat s novým ObjectDataSource s názvem ProductsDataSource. Nakonfigurujte ObjectDataSource pro načtení dat z ProductsBLL metody třídy s GetProducts .
Obrázek 2: Konfigurace ObjectDataSource pro použití ProductsBLL třídy (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 3: Načtení dat o produktu pomocí GetProducts metody (kliknutím zobrazíte obrázek s plnou velikostí)
Podobně jako GridView jsou funkce úprav ObjectDataSource navržené tak, aby fungovaly na jednotlivých řádech. Abychom mohli aktualizovat sadu záznamů, budeme muset napsat část kódu v třídě code-behind stránky ASP.NET, která dávkuje data a předává je do BLL. Proto nastavte rozevírací seznamy na kartách ObjectDataSource – UPDATE, INSERT a DELETE – na (Žádné). Kliknutím na tlačítko Dokončit dokončete průvodce.
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 konfigurací zdroje dat by deklarativní kód ObjectDataSource měl vypadat takto:
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
Dokončení průvodce konfigurací zdroje dat také způsobí, že Visual Studio vytvoří BoundFields a CheckBoxField pro pole dat produktu v GridView. V tomto kurzu umožníme uživateli jenom zobrazit a upravit název produktu, kategorii, cenu a ukončený stav. Odeberte všechna pole kromě ProductName, CategoryName, UnitPrice a Discontinued, a přejmenujte vlastnosti HeaderText prvních tří polí na Product, Category a Price. Nakonec zaškrtněte políčka Povolit stránkování a Povolit řazení v inteligentní značce GridView.
V tomto okamžiku má GridView tři BoundFields (ProductName, CategoryNamea UnitPrice) a CheckBoxField (Discontinued). Potřebujeme převést tato čtyři pole na TemplateFields a pak přesunout rozhraní pro úpravy z TemplateField s EditItemTemplate do jeho ItemTemplate.
Poznámka:
V kurzu Přizpůsobení rozhraní pro úpravu dat jsme prozkoumali vytváření a přizpůsobení polí TemplateFields. Projdeme si kroky převodu BoundFields a CheckBoxFields na TemplateFields a definování jejich rozhraní pro úpravy v jejich ItemTemplate s, ale pokud se zaseknete nebo potřebujete si něco připomenout, neváhejte se vrátit k tomuto dřívějšímu kurzu.
Z chytrého štítku GridView klikněte na odkaz Upravit sloupce a otevřete pole dialogového okna. Dále vyberte jednotlivá pole a klikněte na tlačítko Převést toto pole na odkaz TemplateField.
Obrázek 5: Převod existujících polí BoundField a CheckBoxField na TemplateField
Teď, když je každé pole TemplateField, jsme připraveni přesunout rozhraní pro úpravy z objektu EditItemTemplate s na ItemTemplate s.
Krok 2: Vytvoření ProductName, UnitPrice, a Discontinued editačních rozhraní
Vytvoření rozhraní pro ProductName, UnitPrice, a Discontinued úpravy jsou tématem tohoto kroku a je poměrně jednoduché, protože každé rozhraní je již definováno v TemplateFieldu s EditItemTemplate. Vytvoření editačního rozhraní je o něco náročnější, protože potřebujeme vytvořit rozevírací seznam použitelných kategorií. Toto CategoryName rozhraní pro úpravy je řešeno v kroku 3.
Začněme polem ProductName TemplateField. Klikněte na odkaz Upravit šablony ze smart tagu GridView a rozbalte ProductName na TemplateField EditItemTemplate. Vyberte Textové pole, zkopírujte ho do schránky a vložte ho ProductName do TemplateField s ItemTemplate. Změňte vlastnost TextBox ID na ProductName.
Dále přidejte RequiredFieldValidator do ItemTemplate, aby se zajistilo, že uživatel poskytne hodnotu pro každý název produktu. Nastavte vlastnost ControlToValidate na ProductName, vlastnost ErrorMessage na Je nutné zadat název produktu. A vlastnost Text na *. Po přidání těchto doplňků na obrazovku ItemTemplateby měla obrazovka vypadat podobně jako na obrázku 6.
Obrázek 6: Pole ProductName šablony teď obsahuje Textové pole a RequiredFieldValidator (kliknutím zobrazíte obrázek v plné velikosti).
UnitPrice Pro editační rozhraní začněte zkopírováním TextBoxu ze EditItemTemplate do ItemTemplate. Dále umístěte $ před TextBox a nastavte jeho ID vlastnost na UnitPrice a jeho Columns vlastnost na 8 .
Přidejte také CompareValidator ke UnitPrice s ItemTemplate, aby se zajistilo, že hodnota zadaná uživatelem je platnou měnovou hodnotou větší nebo rovnou částce 0,00 USD. Nastavte vlastnost validátoru ControlToValidate na UnitPrice, jeho ErrorMessage vlastnost na Je nutné zadat platnou hodnotu měny. Prosím vynechte všechny symboly měny, nastavte jeho Text vlastnost na *, jeho Type vlastnost na Currency, jeho Operator vlastnost na GreaterThanEqual, a jeho ValueToCompare vlastnost na 0.
Obrázek 7: Přidání compareValidatoru pro zajištění, že zadaná cena je nezáporná hodnota měny (kliknutím zobrazíte obrázek plné velikosti)
Discontinued Pro TemplateField můžete použít CheckBox již definovaný v objektu ItemTemplate. Jednoduše nastavte jeho ID na Hodnotu Ukončeno a jeho Enabled vlastnost na true.
Krok 3: VytvořeníCategoryNamerozhraní pro úpravy
Rozhraní pro úpravy v CategoryName TemplateField s EditItemTemplate obsahuje TextBox, který zobrazuje hodnotu datového CategoryName pole. Musíme ho nahradit rozevíracím seznamem, který obsahuje seznam možných kategorií.
Poznámka:
Kurz Přizpůsobení rozhraní pro úpravu dat obsahuje důkladnější a ucelenější diskuzi o přizpůsobení šablony tak, aby obsahoval rozevírací seznam místo textového pole. I když jsou zde uvedené kroky hotové, jsou prezentovány stručně. Podrobnější informace o vytváření a konfiguraci kategorií DropDownList najdete v kurzu Přizpůsobení rozhraní pro úpravu dat .
Přetáhněte DropDownList ze sady nástrojů na CategoryName TemplateField a nastavte jeho ItemTemplate na ID. V tomto okamžiku bychom obvykle definovali zdroj dat DropDownLists prostřednictvím své inteligentní značky a vytvořili nový ObjectDataSource. To však přidá ObjectDataSource v rámci ItemTemplate, což bude mít za následek ObjectDataSource instance vytvořené pro každý řádek GridView. Místo toho pojďme vytvořit ObjectDataSource mimo GridView s TemplateFields. Ukončete úpravy šablony a přetáhněte objekt ObjectDataSource ze sady nástrojů do Návrháře pod ProductsDataSource ObjectDataSource. Pojmenujte nový ObjectDataSource CategoriesDataSource a nakonfigurujte ho tak, aby používal metodu CategoriesBLL třídy s GetCategories .
Obrázek 8: Konfigurace ObjectDataSource pro použití CategoriesBLL třídy (kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 9: Načtení dat kategorie pomocí GetCategories metody (kliknutím zobrazíte obrázek s plnou velikostí)
Vzhledem k tomu, že se tento ObjectDataSource používá pouze k načtení dat, nastavte rozevírací seznamy na kartách UPDATE a DELETE na (Žádné). Kliknutím na tlačítko Dokončit dokončete průvodce.
Obrázek 10: Nastavení Drop-Down seznamů na kartách UPDATE a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce CategoriesDataSource by deklarativní kód měl vypadat takto:
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
CategoriesDataSource Po vytvoření a nakonfigurování se vraťte do CategoryName TemplateField s ItemTemplate a klikněte na odkaz Vybrat zdroj dat z DropDownList s smart tag. V průvodci konfigurací zdroje dat vyberte CategoriesDataSource možnost z prvního rozevíracího seznamu a zvolte, že se CategoryName má použít pro zobrazení a CategoryID jako hodnotu.
Obrázek 11: Navázat rozevírací seznam k CategoriesDataSource (kliknutím zobrazíte obrázek v plné velikosti)
V tomto okamžiku Categories dropDownList zobrazí seznam všech kategorií, ale zatím automaticky nevybere odpovídající kategorii produktu vázaného na řádek GridView. Abychom toho dosáhli, musíme nastavit Categories DropDownList s SelectedValue na hodnotu produktu CategoryID . Klikněte na odkaz Upravit datové vazby ze seznamu DropDownList a přidružte vlastnost SelectedValue k datovému poli CategoryID, jak je znázorněno na obrázku 12.
Obrázek 12: Vytvoření vazby CategoryID hodnoty produktu k vlastnosti DropDownList s SelectedValue
Jeden poslední problém zůstává: Pokud produkt nemá zadanou CategoryID hodnotu, příkaz pro vazbu SelectedValue dat způsobí výjimku. Důvodem je, že Rozevírací seznam obsahuje pouze položky pro kategorie a nenabízí možnost pro ty produkty, které mají hodnotu v databázi jako NULL pro CategoryID. Chcete-li to napravit, nastavte vlastnost AppendDataBoundItems objektu DropDownList na true a přidejte novou položku do DropDownList, vynechání vlastnosti Value z deklarativní syntaxe. Ujistěte se, že deklarativní syntaxe Categories DropDownList vypadá následovně:
<asp:DropDownList ID="Categories" runat="server" AppendDataBoundItems="True"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem Value=">-- Select One --</asp:ListItem>
</asp:DropDownList>
Všimněte si, že parametr <asp:ListItem Value=""> -- Select One - má jeho Value atribut explicitně nastavený na prázdný řetězec. Pro podrobnější diskusi o tom, proč je tato další položka DropDownList nezbytná ke zpracování případu a proč je přiřazení vlastnosti NULL k prázdnému řetězci zásadní, se vraťte ke kurzu Value.
Poznámka:
Existuje potenciální problém s výkonem a škálovatelností, který stojí za zmínku. Vzhledem k tomu, že každý řádek má DropDownList, který používá CategoriesDataSource jako zdroj dat, CategoriesBLL metoda třídy s GetCategories bude volána nkrát na stránku, kde n je počet řádků v GridView. Tato volání n mají GetCategories za následek n dotazů do databáze. Tento dopad na databázi může být zmírněn ukládáním vrácených kategorií do mezipaměti buď v mezipaměti pro jednotlivé požadavky, nebo prostřednictvím vrstvy ukládání do mezipaměti pomocí SQL závislosti pro ukládání do mezipaměti nebo velmi krátkou časovou platnost.
Krok 4: Dokončení rozhraní pro úpravy
Provedli jsme řadu změn v šablonách GridView bez pozastavení, abychom viděli průběh. Chvilku si prohlédněte průběh v prohlížeči. Jak ukazuje obrázek 13, každý řádek je vykreslen pomocí svého ItemTemplate, které obsahuje rozhraní pro úpravy buněk.
Obrázek 13: Každý řádek GridView je upravitelný (kliknutím zobrazíte obrázek s plnou velikostí)
V tuto chvíli bychom se měli postarat o několik menších problémů s formátováním. Nejprve si všimněte, že UnitPrice hodnota obsahuje čtyři desetinné čárky. Chcete-li tento problém vyřešit, vraťte se do UnitPrice TemplateField ItemTemplate a z inteligentní značky TextBox klikněte na odkaz Upravit vazby dat. Dále určete, že Text vlastnost by měla být formátována jako číslo.
Obrázek 14: Formátování Text vlastnosti jako čísla
Za druhé, zarovnáme zaškrtávací políčko do Discontinued sloupce (místo toho, aby bylo zarovnané doleva). Klikněte na Upravit sloupce z chytré značky GridView a vyberte Discontinued TemplateField ze seznamu polí v levém dolním rohu. Prozkoumejte ItemStyle a nastavte vlastnost HorizontalAlign na střed, jak je uvedeno na obrázku 15.
Obrázek 15: Vycentrujte Discontinued zaškrtávací políčko
Dále na stránku přidejte ovládací prvek ValidationSummary a nastavte jeho ShowMessageBox vlastnost a jeho true vlastnost na ShowSummaryfalse . Přidejte také webové ovládací prvky tlačítka, které po kliknutí aktualizují změny uživatele. Konkrétně přidejte dva ovládací prvky Button Web, jeden nad GridView a jeden pod ním, u obou ovládacích prvků nastavte vlastnost Text na Aktualizovat produkty.
Vzhledem k tomu, že rozhraní pro úpravy GridView je definováno v jeho TemplateFields ItemTemplate, EditItemTemplate jsou nadbytečné a mohou být odstraněny.
Po provedení výše uvedených změn formátování, přidáním ovládacích prvků tlačítek a odebráním nepotřebných značek EditItemTemplate, by měla deklarativní syntaxe stránky vypadat takto:
<p>
<asp:Button ID="UpdateAllProducts1" runat="server" Text="Update Products" />
</p>
<p>
<asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" AllowSorting="True">
<Columns>
<asp:TemplateField HeaderText="Product" SortExpression="ProductName">
<ItemTemplate>
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Bind("ProductName") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must provide the product's name."
runat="server">*</asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category"
SortExpression="CategoryName">
<ItemTemplate>
<asp:DropDownList ID="Categories" runat="server"
AppendDataBoundItems="True"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName"
DataValueField="CategoryID"
SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem>-- Select One --</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price"
SortExpression="UnitPrice">
<ItemTemplate>
$<asp:TextBox ID="UnitPrice" runat="server" Columns="8"
Text='<%# Bind("UnitPrice", "{0:N}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="UnitPrice"
ErrorMessage="You must enter a valid currency value.
Please omit any currency symbols."
Operator="GreaterThanEqual" Type="Currency"
ValueToCompare="0">*</asp:CompareValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<asp:CheckBox ID="Discontinued" runat="server"
Checked='<%# Bind("Discontinued") %>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
</p>
<p>
<asp:Button ID="UpdateAllProducts2" runat="server" Text="Update Products" />
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
<asp:ValidationSummary ID="ValidationSummary1" runat="server"
ShowMessageBox="True" ShowSummary="False" />
</p>
Obrázek 16 znázorňuje tuto stránku po přidání ovládacích prvků Button Web a provedených změnách formátování v prohlížeči.
Obrázek 16: Stránka teď obsahuje dvě tlačítka aktualizačních produktů (kliknutím zobrazíte obrázek s plnou velikostí)
Krok 5: Aktualizace produktů
Když uživatel navštíví tuto stránku, provede změny a potom klikne na jedno ze dvou tlačítek Aktualizovat produkty. V tomto okamžiku musíme nějak uložit uživatelem zadané hodnoty pro každý řádek do ProductsDataTable instance a pak ji předat metodě BLL, která pak předá danou ProductsDataTable instanci metodě DAL s UpdateWithTransaction . Metoda UpdateWithTransaction , kterou jsme vytvořili v předchozím kurzu, zajišťuje, že se dávka změn aktualizuje jako atomická operace.
Vytvořte metodu s názvem BatchUpdate v BatchUpdate.aspx.cs a přidejte následující kód:
private void BatchUpdate()
{
// Enumerate the GridView's Rows collection and create a ProductRow
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = productsAPI.GetProducts();
foreach (GridViewRow gvRow in ProductsGrid.Rows)
{
// Find the ProductsRow instance in products that maps to gvRow
int productID = Convert.ToInt32(ProductsGrid.DataKeys[gvRow.RowIndex].Value);
Northwind.ProductsRow product = products.FindByProductID(productID);
if (product != null)
{
// Programmatically access the form field elements in the
// current GridViewRow
TextBox productName = (TextBox)gvRow.FindControl("ProductName");
DropDownList categories =
(DropDownList)gvRow.FindControl("Categories");
TextBox unitPrice = (TextBox)gvRow.FindControl("UnitPrice");
CheckBox discontinued =
(CheckBox)gvRow.FindControl("Discontinued");
// Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim();
if (categories.SelectedIndex == 0)
product.SetCategoryIDNull();
else
product.CategoryID = Convert.ToInt32(categories.SelectedValue);
if (unitPrice.Text.Trim().Length == 0)
product.SetUnitPriceNull();
else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text);
product.Discontinued = discontinued.Checked;
}
}
// Now have the BLL update the products data using a transaction
productsAPI.UpdateWithTransaction(products);
}
Tato metoda začíná tím, že získá všechny produkty zpět do ProductsDataTable voláním metody BLL s GetProducts. Potom vytvoří ProductGrid výčet kolekce GridView sRows. Kolekce Rows obsahuje GridViewRow instanci pro každý řádek zobrazený v GridView. Vzhledem k tomu, že na stránce zobrazujeme maximálně deset řádků, kolekce GridView Rows nebude obsahovat více než deset položek.
Pro každý řádek je ProductID převzat z kolekce DataKeys a příslušný ProductsRow je vybrán z ProductsDataTable. Čtyři vstupní ovládací prvky TemplateField jsou programově odkazovány a jejich hodnoty jsou přiřazeny vlastnostem instance ProductsRow. Poté, co byly hodnoty řádků GridView použity k aktualizaci ProductsDataTable, je předán do metody UpdateWithTransaction BLL, která, jak jsme viděli v předchozím kurzu, jednoduše volá do metody UpdateWithTransaction DAL.
Algoritmus dávkové aktualizace použitý pro tento kurz aktualizuje každý řádek, ProductsDataTable který odpovídá řádku v GridView bez ohledu na to, jestli byly informace o produktu změněny. I když tyto neřízené aktualizace obvykle nejsou problémem s výkonem, mohou vést k nadbytečným záznamům, pokud provádíte audit změn v databázových tabulkách. V kurzu provádění dávkových aktualizací jsme prozkoumali rozhraní dávkové aktualizace pomocí dataListu a přidali kód, který by aktualizoval pouze ty záznamy, které byly skutečně upraveny uživatelem. V případě potřeby můžete použít techniky provádění aktualizací služby Batch k aktualizaci kódu v tomto kurzu.
Poznámka:
Při vytváření vazby zdroje dat ke GridView pomocí jeho inteligentní značky, Visual Studio automaticky přiřadí hodnotu primárního klíče zdroje dat k vlastnosti GridView DataKeyNames. Pokud jste nevytvořili vazbu mezi ObjectDataSource a GridView pomocí chytré značky GridView, jak je popsáno v kroku 1, budete muset ručně nastavit tu vlastnost DataKeyNames GridView na ProductID, abyste mohli získat přístup k ProductID hodnotě pro každý řádek skrze DataKeys kolekci.
Kód použitý v BatchUpdate je podobný kódu používanému v metodách BLL UpdateProduct, hlavní rozdíl je v tom, že v metodách UpdateProduct se z architektury načte pouze jedna instance ProductRow. Kód, který přiřazuje vlastnosti ProductRow, je stejný mezi metodami UpdateProducts a kódem v rámci smyčky foreach v BatchUpdate, stejně jako celkový vzor.
K dokončení tohoto kurzu musíme metodu BatchUpdate vyvolat při kliknutí na některé z tlačítek Update Products. Vytvořte obslužné rutiny událostí pro Click události těchto dvou ovládacích prvků Button a přidejte do obslužných rutin událostí následující kód:
BatchUpdate();
ClientScript.RegisterStartupScript(this.GetType(), "message",
"alert('The products have been updated.');", true);
Nejprve se provede volání na BatchUpdate. Dále se ClientScript property používá k vložení JavaScriptu, který zobrazí pole se zprávou s textem: Produkty byly aktualizovány.
Otestujte tento kód za minutu. Přistupte k BatchUpdate.aspx prostřednictvím prohlížeče, upravte několik řádků a klikněte na jedno z tlačítek Aktualizovat produkty. Za předpokladu, že nedošlo k žádným chybám ověření vstupu, měla by se zobrazit zpráva s textem: Produkty byly aktualizovány. Pokud chcete ověřit atomicitu aktualizace, zvažte přidání náhodného CHECK omezení, jako je ten, který zakáže UnitPrice hodnoty 1234,56. Potom z BatchUpdate.aspx upravte několik záznamů a ujistěte se, že je jedna z hodnot produktu UnitPrice nastavena na zakázanou hodnotu (1234.56). Výsledkem by měla být chyba při kliknutí na Aktualizace produktů, když se všechny ostatní změny provedené během této dávkové operace vrátí k původním hodnotám.
AlternativníBatchUpdatemetoda
Metoda BatchUpdate , kterou jsme právě prozkoumali, načte všechny produkty z metody BLL a GetProducts pak aktualizuje pouze ty záznamy, které se zobrazí v GridView. Tento přístup je ideální, pokud GridView nepoužívá stránkování, ale pokud ano, může existovat stovky, tisíce nebo desítky tisíc produktů, ale pouze deset řádků v GridView. V takovém případě není ideální získávat všechny produkty z databáze pouze k úpravě 10 z nich.
U těchto typů situací zvažte místo toho použití následující BatchUpdateAlternate metody:
private void BatchUpdateAlternate()
{
// Enumerate the GridView's Rows collection and create a ProductRow
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();
foreach (GridViewRow gvRow in ProductsGrid.Rows)
{
// Create a new ProductRow instance
int productID = Convert.ToInt32(ProductsGrid.DataKeys[gvRow.RowIndex].Value);
Northwind.ProductsDataTable currentProductDataTable =
productsAPI.GetProductByProductID(productID);
if (currentProductDataTable.Rows.Count > 0)
{
Northwind.ProductsRow product = currentProductDataTable[0];
// Programmatically access the form field elements in the
// current GridViewRow
TextBox productName = (TextBox)gvRow.FindControl("ProductName");
DropDownList categories =
(DropDownList)gvRow.FindControl("Categories");
TextBox unitPrice = (TextBox)gvRow.FindControl("UnitPrice");
CheckBox discontinued =
(CheckBox)gvRow.FindControl("Discontinued");
// Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim();
if (categories.SelectedIndex == 0)
product.SetCategoryIDNull();
else
product.CategoryID = Convert.ToInt32(categories.SelectedValue);
if (unitPrice.Text.Trim().Length == 0)
product.SetUnitPriceNull();
else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text);
product.Discontinued = discontinued.Checked;
// Import the ProductRow into the products DataTable
products.ImportRow(product);
}
}
// Now have the BLL update the products data using a transaction
productsAPI.UpdateProductsWithTransaction(products);
}
BatchMethodAlternate začíná vytvořením nového prázdného ProductsDataTable názvu products. Pak prochází kolekci GridView pomocí Rows a pro každý řádek získá konkrétní informace o produktu prostřednictvím metody BLL pomocí GetProductByProductID(productID). Načtená ProductsRow instance má své vlastnosti aktualizované stejným způsobem jako BatchUpdate, ale po aktualizaci řádku se importuje do products``ProductsDataTable pomocí metody DataTable ImportRow(DataRow).
Po dokončení smyčky obsahuje foreach jednu instanci products pro každý řádek v GridView. Vzhledem k tomu, že každá instance ProductsRow byla přidána do products (místo aktualizace), pokud ji bez rozmyslu předáme metodě UpdateWithTransaction, ProductsTableAdapter pokusí se vložit každý záznam do databáze. Místo toho musíme určit, že každý z těchto řádků byl změněn (nepřidá se).
Toho lze dosáhnout přidáním nové metody do BLL s názvem UpdateProductsWithTransaction.
UpdateProductsWithTransaction, jak je znázorněno níže, nastaví RowState každé instance ProductsRow v ProductsDataTable na Modified a pak předá ProductsDataTable metodě DAL UpdateWithTransaction.
public int UpdateProductsWithTransaction(Northwind.ProductsDataTable products)
{
// Mark each product as Modified
products.AcceptChanges();
foreach (Northwind.ProductsRow product in products)
product.SetModified();
// Update the data via a transaction
return UpdateWithTransaction(products);
}
Shrnutí
GridView poskytuje integrované možnosti úprav pro jednotlivé řádky, ale nemá podporu pro vytváření plně upravitelných rozhraní. Jak jsme viděli v tomto kurzu, taková rozhraní jsou možná, ale vyžadují trochu práce. Chcete-li vytvořit GridView, kde je každý řádek upravitelný, musíme převést pole GridView na TemplateFields a definovat rozhraní pro úpravy v rámci ItemTemplate s. Kromě toho je nutné odděleně od GridView přidat na stránku webové ovládací prvky pro tlačítko aktualizace všech funkcí označené -type. Tyto obslužné rutiny událostí Tlačítka Click musí vytvořit výčet kolekce GridView s Rows , uložit změny do ProductsDataTablea a předat aktualizované informace do příslušné metody BLL.
V dalším kurzu se dozvíte, jak vytvořit rozhraní pro dávkové odstraňování. Každý řádek GridView bude obsahovat zaškrtávací políčko a místo tlačítka Aktualizovat vše -type budeme mít tlačítka Odstranit vybrané řádky.
Šťastné programování!
O autorovi
Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams 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í recenzenti tohoto kurzu byli Teresa Murphy a David Suru. Chcete si projít nadcházející články MSDN? Pokud ano, napište mi zprávu na mitchell@4GuysFromRolla.com.