Dávkové aktualizace (VB)
Naučte se aktualizovat více databázových záznamů v jedné operaci. Ve vrstvě uživatelského rozhraní vytvoříme GridView, kde je možné upravovat každý řádek. Ve vrstvě přístupu k datům zabalíme několik operací aktualizace v rámci transakce, abychom zajistili, že všechny aktualizace budou úspěšné nebo se vrátí zpět.
Úvod
V předchozím kurzu jsme viděli, jak rozšířit vrstvu přístupu k datům, aby se přidala podpora databázových transakcí. Databázové transakce zaručují, že řada příkazů úprav dat bude považována za jednu atomickou operaci, což zajistí, že všechny úpravy selžou nebo všechny budou úspěšné. S touto nízkoúrovňovou funkcí DAL jsme připraveni obrátit svou pozornost na vytváření rozhraní pro dávkové úpravy dat.
V tomto kurzu vytvoříme GridView, ve kterém bude možné upravovat každý řádek (viz obrázek 1). Vzhledem k tomu, že se každý řádek vykresluje ve svém rozhraní pro úpravy, není potřeba použít sloupec tlačítek Upravit, Aktualizovat a Zrušit. Místo toho jsou na stránce dvě tlačítka Aktualizovat produkty, která po kliknutí zobrazí výčet řádků GridView a aktualizují databázi.
Obrázek 1: Každý řádek v zobrazení GridView je upravitelný (kliknutím zobrazíte obrázek v plné velikosti)
Pojďme začít!
Poznámka
V kurzu Provádění služby Batch Aktualizace jsme vytvořili rozhraní pro úpravy dávky pomocí ovládacího prvku DataList. Tento kurz 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 vám doporučujeme vrátit se k předchozímu kurzu a aktualizovat ho tak, aby používal funkce související s databázovými transakcemi přidané v předchozím kurzu.
Prozkoumání kroků pro úpravu všech řádků GridView
Jak je popsáno v kurzu Přehled vkládání, aktualizace a odstraňování dat , GridView nabízí integrovanou podporu pro úpravy podkladových dat po jednotlivých řádcích. GridView interně zaznamená, jaký řádek je možné upravit prostřednictvím své EditIndex
vlastnosti. Vzhledem k tomu, že objekt GridView je svázán se svým zdrojem dat, kontroluje každý řádek a zjišťuje, jestli se index řádku rovná hodnotě EditIndex
. Pokud ano, tato pole řádků se vykreslují pomocí jejich rozhraní pro úpravy. Pro BoundFields je rozhraní pro úpravy TextBox, jehož Text
vlastnost je přiřazena hodnota datového pole určená BoundField s DataField
vlastnost. Pro TemplateFields se EditItemTemplate
místo ItemTemplate
.
Vzpomeňte si, že pracovní postup úprav se spustí, když uživatel klikne na tlačítko Upravit na řádku. To způsobí postback, nastaví vlastnost GridView s EditIndex
na index klepaného řádku s a znovu přidružuje data k mřížce. Když kliknete na tlačítko Zrušit v řádku, nastaví se při postbacku EditIndex
hodnota na hodnotu -1
před opětovným navázáním dat do mřížky. Vzhledem k tomu, že řádky GridView s začínají indexovat na nule, má nastavení EditIndex
na -1
výsledek zobrazení GridView v režimu jen pro čtení.
Vlastnost EditIndex
funguje dobře pro úpravy podle řádků, ale není určená pro dávkové úpravy. Aby bylo možné upravovat celý Objekt GridView, musíme každý řádek vykreslit pomocí jeho rozhraní pro úpravy. Nejjednodušší způsob, jak toho dosáhnout, je vytvořit, kde se každé upravitelné pole implementuje jako TemplateField s jeho rozhraním pro úpravy definovaným ItemTemplate
v .
V dalších několika krocích vytvoříme zcela upravitelné zobrazení GridView. V kroku 1 začneme vytvořením objektu GridView a jeho objektu ObjectDataSource a převedeme jeho BoundFields a CheckBoxField na TemplateFields. V krocích 2 a 3 přesuneme rozhraní pro úpravy z polí šablon EditItemTemplate
do jejich ItemTemplate
polí.
Krok 1: Zobrazení informací o produktu
Než se začneme 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 Designer. Nastavte GridView na ID
ProductsGrid
a z jeho inteligentní značky zvolte jeho vazbu na nový ObjectDataSource s názvem ProductsDataSource
. Nakonfigurujte ObjectDataSource tak, aby načetl data z ProductsBLL
metody třídy s GetProducts
.
Obrázek 2: Konfigurace objektu 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 v plné velikosti)
Stejně jako u GridView jsou funkce úprav ObjectDataSource navržené tak, aby fungovaly na základě jednotlivých řádků. Abychom mohli aktualizovat sadu záznamů, budeme muset do třídy kódu na pozadí ASP.NET stránky napsat trochu kódu, který data dávkuje a předá do BLL. Proto nastavte rozevírací seznamy na kartách ObjectDataSource s UPDATE, INSERT a DELETE na (None). Dokončete průvodce kliknutím na Dokončit.
Obrázek 4: Nastavení Drop-Down Seznamy na kartách UPDATE, INSERT a DELETE na (Žádný) (Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce konfigurací zdroje dat by deklarativní značka ObjectDataSource s měla vypadat takto:
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
Dokončení průvodce Konfigurovat zdroj dat také způsobí, že Visual Studio vytvoří BoundFields a CheckBoxField pro pole dat produktu v GridView. Pro účely tohoto kurzu umožníte uživateli jenom zobrazit a upravit název produktu, kategorii, cenu a stav ukončeného produktu. Odeberte všechna pole kromě ProductName
, CategoryName
, UnitPrice
a Discontinued
přejmenujte HeaderText
vlastnosti prvních tří polí na Product (Produkt), Category (Kategorie) a Price (Cena). Nakonec zaškrtněte políčka Povolit stránkování a Povolit řazení v inteligentní značce GridView.
V tomto okamžiku má Objekt GridView tři BoundFields (ProductName
, CategoryName
a UnitPrice
) a CheckBoxField (Discontinued
). Musíme 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í šablon. Projdeme si kroky převodu BoundFields a CheckBoxField na TemplateFields a definování jejich rozhraní pro úpravy v jejich ItemTemplate
s, ale pokud se zaseknete nebo potřebujete aktualizovat, neváhejte se vrátit k tomuto dřívějšímu kurzu.
V inteligentní značce GridView klikněte na odkaz Upravit sloupce a otevřete dialogové okno Pole. Potom vyberte jednotlivá pole a klikněte na odkaz Převést toto pole na TemplateField.
Obrázek 5: Převod existujících boundfields a CheckBoxField na templateFields
Teď, když je každé pole Pole šablony, jsme připraveni přesunout rozhraní pro úpravy z EditItemTemplate
s na ItemTemplate
s.
Krok 2: VytvořeníProductName
UnitPrice
Discontinued
rozhraní a úprav
ProductName
Vytváření rozhraní , UnitPrice
a Discontinued
úpravy jsou tématem tohoto kroku a jsou poměrně jednoduché, protože každé rozhraní je již definováno v TemplateField s EditItemTemplate
. CategoryName
Vytvoření rozhraní pro úpravy je trochu více zapojeno, protože potřebujeme vytvořit Rozevírací seznam příslušný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 z inteligentní značky GridView a přejděte k podrobnostem ProductName
TemplateField s EditItemTemplate
. Vyberte Textové pole, zkopírujte ho do schránky a vložte ho ProductName
do pole TemplateField s ItemTemplate
. Změňte vlastnost TextBox s ID
na ProductName
.
Dále přidejte requiredFieldValidator do objektu ItemTemplate
, abyste zajistili, že uživatel zadá hodnotu pro každý název produktu. Vlastnost nastavte ControlToValidate
na ProductName, ErrorMessage
vlastnost na Musíte zadat název produktu. Text
a vlastnost *. Po provedení těchto přidání do ItemTemplate
nástroje by 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 rozhraní pro úpravy začněte zkopírováním textového pole z pole 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 k hodnotě UnitPrice
s ItemTemplate
, abyste zajistili, že hodnota zadaná uživatelem je platná hodnota měny větší nebo rovna 0,00 USD. Nastavte vlastnost validátoru ControlToValidate
na UnitPrice, její ErrorMessage
vlastnost na Hodnotu Musíte zadat platnou hodnotu měny. Vyněnejte všechny symboly měny, jeho Text
vlastnost *, jeho Type
vlastnost do Currency
, jeho Operator
vlastnost na GreaterThanEqual
a jeho ValueToCompare
vlastnost na hodnotu 0 .
Obrázek 7: Přidání compareValidatoru k zajištění, že zadaná cena je nezáporná hodnota měny (kliknutím zobrazíte obrázek v plné velikosti)
Discontinued
Pro TemplateField můžete použít CheckBox, který je již definován v objektu ItemTemplate
. Jednoduše nastavte jeho ID
hodnotu na Ukončeno a jeho Enabled
vlastnost na True
.
Krok 3: VytvořeníCategoryName
rozhraní 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 zahrnovala rozevírací seznam namísto textového pole. Po dokončení jsou zde uvedené kroky prezentovány tersely. Podrobnější informace o vytváření a konfiguraci kategorií DropDownList najdete v kurzu Přizpůsobení rozhraní pro úpravu dat .
Přetáhněte rozevírací seznam z panelu nástrojů na CategoryName
TemplateField s ItemTemplate
a nastavujte jeho ID
hodnotu na Categories
. V tomto okamžiku bychom obvykle definovali zdroj dat DropDownLists prostřednictvím inteligentní značky a vytvořili tak nový ObjectDataSource. To však přidá ObjectDataSource v , ItemTemplate
což bude mít za následek ObjectDataSource instance vytvořená pro každý řádek GridView. Místo toho vytvoří ObjectDataSource mimo GridView s TemplateFields. Ukončete úpravy šablony a přetáhněte ObjectDataSource z panelu nástrojů na Designer pod ProductsDataSource
ObjectDataSource. Pojmenujte nový ObjektDataSource CategoriesDataSource
a nakonfigurujte ho tak, aby používal metodu CategoriesBLL
třídy s GetCategories
.
Obrázek 8: Konfigurace objektu ObjectDataSource pro použití CategoriesBLL
třídy (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 9: Načtení dat kategorie pomocí GetCategories
metody (kliknutím zobrazíte obrázek v plné velikosti)
Vzhledem k tomu, že se tento objekt ObjectDataSource používá jenom k načtení dat, nastavte rozevírací seznamy na kartách UPDATE a DELETE na (None). Dokončete průvodce kliknutím na Dokončit.
Obrázek 10: Nastavte Drop-Down Seznamy na kartách UPDATE (UPDATE) a DELETE (Žádný) (Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce CategoriesDataSource
by deklarativní kód s měl vypadat takto:
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
S vytvořeným CategoriesDataSource
a nakonfigurovaným objektem se vraťte do CategoryName
pole TemplateField ItemTemplate
a z inteligentní značky DropDownList klikněte na odkaz Zvolit zdroj dat. 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: Svázání rozevíracího seznamu s CategoriesDataSource
(kliknutím zobrazíte obrázek v plné velikosti)
V tomto okamžiku Categories
DropDownList seznam všech kategorií, ale ještě automaticky nevybere příslušnou kategorii pro produkt vázaný na řádek GridView. Abychom toho dosáhli, musíme nastavit Categories
DropDownList na SelectedValue
hodnotu produktu CategoryID
. Klikněte na odkaz Upravit datové vazby z inteligentní značky DropDownList a přidružte SelectedValue
vlastnost k datovému CategoryID
poli, jak je znázorněno na obrázku 12.
Obrázek 12: Vazba hodnoty Product s CategoryID
na vlastnost DropDownList s SelectedValue
Poslední problém přetrvává: Pokud produkt nemá zadanou CategoryID
hodnotu, výsledkem příkazu SelectedValue
databinding pro bude výjimka. Je to proto, že rozevírací seznam obsahuje pouze položky pro kategorie a nenabízí možnost pro produkty, které mají NULL
hodnotu databáze pro CategoryID
. Chcete-li tento problém napravit, nastavte vlastnost DropDownList na AppendDataBoundItems
True
a přidejte novou položku dropDownList, přičemž vynecháte Value
vlastnost z deklarativní syntaxe. To znamená, že Categories
deklarativní syntaxe DropDownList vypadá takto:
<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 <asp:ListItem Value="">
má -- Select One -- svůj Value
atribut explicitně nastavený na prázdný řetězec. Projděte si kurz Přizpůsobení rozhraní pro úpravu dat , kde najdete podrobnější diskuzi o tom, proč je tato další položka DropDownList potřebná ke zpracování NULL
případu a proč je přiřazení Value
vlastnosti k prázdnému řetězci nezbytné.
Poznámka
Existuje zde 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
bude metoda třídy s GetCategories
volána n krát za návštěvu stránky, kde n je počet řádků v GridView. Výsledkem těchto n volání je GetCategories
n dotazů na databázi. Tento dopad na databázi je možné zmenšit ukládáním vrácených kategorií do mezipaměti pro jednotlivé požadavky nebo prostřednictvím vrstvy ukládání do mezipaměti pomocí závislosti sql ukládání do mezipaměti nebo velmi krátké vypršení platnosti v závislosti na čase.
Krok 4: Dokončení rozhraní pro úpravy
Provedli jsme řadu změn v šablonách GridView s bez pozastavení, abychom mohli zobrazit náš postup. Podívejte se na průběh v prohlížeči. Jak ukazuje obrázek 13, každý řádek se vykreslí 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 v plné velikosti)
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. Pokud chcete tento problém vyřešit, vraťte se do UnitPrice
pole TemplateField a ItemTemplate
z inteligentní značky TextBox s klikněte na odkaz Upravit datové vazby. Dále určete, že Text
vlastnost má být formátována jako číslo.
Obrázek 14: Formátování Text
vlastnosti jako čísla
Za druhé zarovnáme políčko ve sloupci na Discontinued
střed (místo toho, aby bylo zarovnané doleva). Klikněte na Upravit sloupce z inteligentní značky GridView a vyberte Discontinued
TemplateField ze seznamu polí v levém dolním rohu. Přejděte k ItemStyle
podrobnostem HorizontalAlign
a nastavte vlastnost na Center, jak je znázorněno na obrázku 15.
Obrázek 15: Zacentrujte Discontinued
zaškrtávací políčko
Dále na stránku přidejte ovládací prvek ValidationSummary a nastavte jeho ShowMessageBox
vlastnost na True
a jeho ShowSummary
vlastnost na False
. Přidejte také webové ovládací prvky Button, které po kliknutí aktualizují změny uživatele. Konkrétně přidejte dva webové ovládací prvky Button, jeden nad GridView a jeden pod něj, nastavení obou ovládacích prvků Text
vlastnosti na Update Products .
Vzhledem k tomu GridView s editing rozhraní je definována v jeho TemplateFields ItemTemplate
s, EditItemTemplate
s jsou nadbytečné a mohou být odstraněny.
Po provedení výše uvedených změn formátování, přidání ovládacích prvků Tlačítko a odebrání nepotřebných EditItemTemplate
s by deklarativní syntaxe stránky měla 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 při prohlížení v prohlížeči po přidání webových ovládacích prvků Button a provedení změn formátování.
Obrázek 16: Stránka teď obsahuje dvě tlačítka pro aktualizaci produktů (kliknutím zobrazíte obrázek v plné velikosti)
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ým způsobem uložit uživatelem zadané hodnoty pro každý řádek do ProductsDataTable
instance a pak je 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
in BatchUpdate.aspx.vb
a přidejte následující kód:
Private Sub BatchUpdate()
' Enumerate the GridView's Rows collection and create a ProductRow
Dim productsAPI As New ProductsBLL()
Dim products As Northwind.ProductsDataTable = productsAPI.GetProducts()
For Each gvRow As GridViewRow In ProductsGrid.Rows
' Find the ProductsRow instance in products that maps to gvRow
Dim productID As Integer = _
Convert.ToInt32(ProductsGrid.DataKeys(gvRow.RowIndex).Value)
Dim product As Northwind.ProductsRow = products.FindByProductID(productID)
If product IsNot Nothing Then
' Programmatically access the form field elements in the
' current GridViewRow
Dim productName As TextBox = _
CType(gvRow.FindControl("ProductName"), TextBox)
Dim categories As DropDownList = _
CType(gvRow.FindControl("Categories"), DropDownList)
Dim unitPrice As TextBox = _
CType(gvRow.FindControl("UnitPrice"), TextBox)
Dim discontinued As CheckBox = _
CType(gvRow.FindControl("Discontinued"), CheckBox)
' Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim()
If categories.SelectedIndex = 0 Then
product.SetCategoryIDNull()
Else
product.CategoryID = Convert.ToInt32(categories.SelectedValue)
End If
If unitPrice.Text.Trim().Length = 0 Then
product.SetUnitPriceNull()
Else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text)
End If
product.Discontinued = discontinued.Checked
End If
Next
' Now have the BLL update the products data using a transaction
productsAPI.UpdateWithTransaction(products)
End Sub
Tato metoda začíná získáním všech produktů zpět do ProductsDataTable
prostřednictvím volání metody BLL s GetProducts
. Pak 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ů, nebude kolekce GridView Rows
obsahovat více než deset položek.
Pro každý řádek se ProductID
z kolekce vybere DataKeys
příslušný ProductsRow
řádek a v ProductsDataTable
. Čtyři ovládací prvky TemplateField vstup jsou programově odkazovány a jejich hodnoty přiřazeny ProductsRow
vlastnosti instance s. Po použití každé hodnoty řádku GridView k aktualizaci ProductsDataTable
se předá do metody BLL s UpdateWithTransaction
, která, jak jsme viděli v předchozím kurzu, jednoduše zavolá metodu DAL s UpdateWithTransaction
.
Algoritmus dávkové aktualizace použitý v tomto kurzu aktualizuje každý řádek v objektu ProductsDataTable
, který odpovídá řádku v GridView, bez ohledu na to, zda byly změněny informace o produktu. I když tyto slepé aktualizace obvykle nejsou problémem s výkonem, můžou vést k nadbytečným záznamům, pokud auditujete změny v tabulce databáze. V kurzu Provádění služby Batch Aktualizace jsme prozkoumali rozhraní dávkové aktualizace pomocí dataList a přidali jsme kód, který by aktualizoval pouze ty záznamy, které byly ve skutečnosti změněny uživatelem. V případě potřeby můžete k aktualizaci kódu v tomto kurzu použít techniky z článku Provádění Aktualizace Batch.
Poznámka
Při vytváření vazby zdroje dat na GridView prostřednictvím inteligentní značky Visual Studio automaticky přiřadí hodnoty primárního klíče zdroje dat vlastnosti GridView DataKeyNames
. Pokud jste nevytvořili vazbu ObjectDataSource na GridView prostřednictvím inteligentní značky GridView, jak je popsáno v kroku 1, budete muset ručně nastavit vlastnost GridView s DataKeyNames
na ProductID, abyste získali přístup k ProductID
hodnotě pro každý řádek prostřednictvím DataKeys
kolekce.
Kód použitý v BatchUpdate
je podobný kódu použitému v metodách BLL s UpdateProduct
, hlavní rozdíl spočívá v tom, že v UpdateProduct
metodách je z architektury načtena pouze jedna ProductRow
instance. Kód, který přiřazuje vlastnosti objektu ProductRow
, je stejný mezi UpdateProducts
metodami a kódem ve For Each
smyčce v BatchUpdate
objektu , stejně jako celkový vzor.
K dokončení tohoto kurzu musíme mít metodu BatchUpdate
vyvolanou, když kliknete na některé z tlačítek Aktualizovat produkty. Vytvořte obslužné rutiny událostí pro Click
události těchto dvou ovládacích prvků Tlačítko a přidejte do obslužných rutin událostí následující kód:
BatchUpdate()
ClientScript.RegisterStartupScript(Me.GetType(), "message", _
"alert('The products have been updated.');", True)
Nejprve se provede volání do BatchUpdate
. Dále se vlastnost použije k vložení JavaScriptu, ClientScript
který zobrazí okno zprávy s textem Produkty byly aktualizovány.
Chvíli si tento kód otestujte. Přejděte BatchUpdate.aspx
do prohlížeče, upravte několik řádků a klikněte na jedno z tlačítek Aktualizovat produkty. Za předpokladu, že nedochází k žádným chybám ověřování vstupu, by se mělo zobrazit okno se zprávou Produkty byly aktualizovány. Pokud chcete ověřit nedělitelnost aktualizace, zvažte přidání náhodného CHECK
omezení, například takového, které nepovoluje UnitPrice
hodnoty 1234,56. Potom v BatchUpdate.aspx
části upravte několik záznamů a nastavte jednu z hodnot produktu UnitPrice
na hodnotu Zakázáno ( 1234,56 ). Výsledkem by měla být chyba při kliknutí na Aktualizovat produkty s vrácením ostatních změn během této dávkové operace zpět na původní hodnoty.
AlternativníBatchUpdate
metoda
Metoda BatchUpdate
, kterou jsme právě prozkoumali, načte všechny produkty z metody BLL s GetProducts
a 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ě je získání všech produktů z databáze pouze k úpravě 10 z nich méně než ideální.
Pro tyto typy situací zvažte místo toho použití následující BatchUpdateAlternate
metody:
Private Sub BatchUpdateAlternate()
' Enumerate the GridView's Rows collection and create a ProductRow
Dim productsAPI As New ProductsBLL()
Dim products As New Northwind.ProductsDataTable()
For Each gvRow As GridViewRow In ProductsGrid.Rows
' Create a new ProductRow instance
Dim productID As Integer = _
Convert.ToInt32(ProductsGrid.DataKeys(gvRow.RowIndex).Value)
Dim currentProductDataTable As Northwind.ProductsDataTable = _
productsAPI.GetProductByProductID(productID)
If currentProductDataTable.Rows.Count > 0 Then
Dim product As Northwind.ProductsRow = currentProductDataTable(0)
Dim productName As TextBox = _
CType(gvRow.FindControl("ProductName"), TextBox)
Dim categories As DropDownList = _
CType(gvRow.FindControl("Categories"), DropDownList)
Dim unitPrice As TextBox = _
CType(gvRow.FindControl("UnitPrice"), TextBox)
Dim discontinued As CheckBox = _
CType(gvRow.FindControl("Discontinued"), CheckBox)
' Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim()
If categories.SelectedIndex = 0 Then
product.SetCategoryIDNull()
Else
product.CategoryID = Convert.ToInt32(categories.SelectedValue)
End If
If unitPrice.Text.Trim().Length = 0 Then
product.SetUnitPriceNull()
Else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text)
End If
product.Discontinued = discontinued.Checked
' Import the ProductRow into the products DataTable
products.ImportRow(product)
End If
Next
' Now have the BLL update the products data using a transaction
productsAPI.UpdateProductsWithTransaction(products)
End Sub
BatchMethodAlternate
Začíná vytvořením nového prázdného ProductsDataTable
s názvem products
. Pak prochází kolekci GridView Rows
s a pro každý řádek získá informace o konkrétním produktu pomocí metody BLL s 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
prostřednictvím metody DataTable sImportRow(DataRow)
.
Po dokončení For Each
smyčky obsahuje products
jednu ProductsRow
instanci pro každý řádek v GridView. Vzhledem k tomu, že každá z ProductsRow
instancí byla přidána do products
(místo aktualizace), pokud je UpdateWithTransaction
slepě předáme metodě ProductsTableAdapter
, pokusí se každý ze záznamů vložit do databáze. Místo toho musíme určit, že každý z těchto řádků byl změněn (nikoli přidán).
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ždou instanci ProductsRow
v objektu ProductsDataTable
do Modified
a pak předá ProductsDataTable
do metody DAL s UpdateWithTransaction
.
Public Function UpdateProductsWithTransaction _
(ByVal products As Northwind.ProductsDataTable) As Integer
' Mark each product as Modified
products.AcceptChanges()
For Each product As Northwind.ProductsRow In products
product.SetModified()
Next
' Update the data via a transaction
Return UpdateWithTransaction(products)
End Function
Souhrn
GridView poskytuje integrované možnosti úprav po řádcích, ale postrádá 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. Pokud chcete vytvořit Objekt GridView, kde je možné upravovat každý řádek, musíme převést pole GridView s na TemplateFields a definovat rozhraní pro úpravy v rámci ItemTemplate
s. Kromě toho, Update All -type Button Web ovládací prvky musí být přidány na stránku, odděleně od GridView. Tyto obslužné rutiny událostí Tlačítka Click
musí vytvořit výčet GridView Rows
s kolekce, uložit změny v objektu ProductsDataTable
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é odstranění. Konkrétně každý řádek GridView bude obsahovat zaškrtávací políčko a místo tlačítek Aktualizovat všechny typy budeme mít tlačítka Odstranit vybrané řádky.
Všechno nejlepší na programování!
O autorovi
Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byli Teresa Murphy a David Suru. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro