Provádění dávkových aktualizací (VB)
Scott Mitchell
Zjistěte, jak vytvořit plně upravitelný datový seznam, kde jsou všechny její položky v režimu úprav a jejichž hodnoty lze uložit kliknutím na tlačítko Aktualizovat vše na stránce.
Úvod
V předchozím kurzu jsme prozkoumali, jak vytvořit DataList na úrovni položky. Stejně jako standardní upravitelné GridView, každá položka v Prvku DataList obsahovala tlačítko Upravit, které by po kliknutí bylo možné položku upravit. I když úpravy na úrovni položek fungují dobře pro data, která se aktualizují jen občas, určité scénáře použití vyžadují, aby uživatel upravil mnoho záznamů. Pokud uživatel potřebuje upravit desítky záznamů a je nucen kliknout na Upravit, udělat změny a kliknout na Aktualizovat pro každou z nich, množství kliknutí může bránit její produktivitě. Vtakovýchch funkcích je v takových situacích lepší možností poskytnout plně upravitelný datový seznam, kde jsou všechny její položky v režimu úprav a jejichž hodnoty je možné upravit kliknutím na tlačítko Aktualizovat vše na stránce (viz obrázek 1).
Obrázek 1: Každou položku v plně upravitelném datovém seznamu lze upravit (kliknutím zobrazíte obrázek v plné velikosti).
V tomto kurzu se podíváme, jak uživatelům umožnit aktualizovat informace o adresách dodavatelů pomocí plně upravitelného datového seznamu.
Krok 1: Vytvoření upravitelného uživatelského rozhraní v Prvku DataList s ItemTemplate
V předchozím kurzu, kde jsme vytvořili standardní seznam dat na úrovni položek, jsme použili dvě šablony:
ItemTemplate
obsahovalo uživatelské rozhraní jen pro čtení (ovládací prvky Label Web pro zobrazení názvu a ceny jednotlivých produktů).EditItemTemplate
obsahoval uživatelské rozhraní režimu úprav (dva ovládací prvky TextBox Web).
Vlastnost DataList s EditItemIndex
určuje, co DataListItem
(pokud existuje) je vykreslen pomocí EditItemTemplate
. Konkrétně, DataListItem
jehož ItemIndex
hodnota odpovídá DataList s EditItemIndex
vlastnost je vykreslen pomocí EditItemTemplate
. Tento model funguje dobře, když lze současně upravovat jenom jednu položku, ale při vytváření plně upravitelného datového seznamu se rozdělí.
Pro plně upravitelný DataList chceme , aby se všechny objekty DataListItem
vykreslovat pomocí upravitelného rozhraní. Nejjednodušším způsobem, jak toho dosáhnout, je definovat upravitelné rozhraní v souboru ItemTemplate
. Při úpravě informací o adrese dodavatelů obsahuje upravitelné rozhraní název dodavatele jako text a textová pole pro hodnoty adresy, města a země/oblasti.
Začněte otevřením BatchUpdate.aspx
stránky, přidáním ovládacího prvku DataList a nastavením jeho ID
vlastnosti na Suppliers
. Z inteligentní značky DataList se přihlaste k přidání nového ovládacího prvku ObjectDataSource s názvem SuppliersDataSource
.
Obrázek 2: Vytvoření nového objektu ObjectDataSource s názvem SuppliersDataSource
(kliknutím zobrazíte obrázek s plnou velikostí)
Nakonfigurujte ObjectDataSource pro načtení dat pomocí SuppliersBLL
metody třídy s GetSuppliers()
(viz obrázek 3). Stejně jako v předchozím kurzu místo aktualizace informací o dodavateli prostřednictvím ObjectDataSource budeme pracovat přímo s vrstvou obchodní logiky. Proto nastavte rozevírací seznam na (Žádný) na kartě UPDATE (viz obrázek 4).
Obrázek 3: Načtení informací o dodavateli pomocí GetSuppliers()
metody (kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 4: Nastavení rozevíracího seznamu na hodnotu (Žádné) na kartě UPDATE (kliknutím zobrazíte obrázek s plnou velikostí)
Po dokončení průvodce sada Visual Studio automaticky vygeneruje dataList s ItemTemplate
, aby se zobrazilo každé datové pole vrácené zdrojem dat v ovládacím prvku Label Web. Tuto šablonu potřebujeme upravit tak, aby poskytovala rozhraní pro úpravy. Lze ItemTemplate
přizpůsobit prostřednictvím Návrháře pomocí možnosti Upravit šablony z inteligentní značky DataList nebo přímo prostřednictvím deklarativní syntaxe.
Chvíli si vytvořte rozhraní pro úpravy, které zobrazuje název dodavatele jako text, ale obsahuje textová pole pro adresu dodavatele, město a hodnoty země/oblasti. Po provedení těchto změn by deklarativní syntaxe stránky měla vypadat nějak takto:
<asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID"
DataSourceID="SuppliersDataSource">
<ItemTemplate>
<h4><asp:Label ID="CompanyNameLabel" runat="server"
Text='<%# Eval("CompanyName") %>' /></h4>
<table border="0">
<tr>
<td class="SupplierPropertyLabel">Address:</td>
<td class="SupplierPropertyValue">
<asp:TextBox ID="Address" runat="server"
Text='<%# Eval("Address") %>' />
</td>
</tr>
<tr>
<td class="SupplierPropertyLabel">City:</td>
<td class="SupplierPropertyValue">
<asp:TextBox ID="City" runat="server"
Text='<%# Eval("City") %>' />
</td>
</tr>
<tr>
<td class="SupplierPropertyLabel">Country:</td>
<td class="SupplierPropertyValue">
<asp:TextBox ID="Country" runat="server"
Text='<%# Eval("Country") %>' />
</td>
</tr>
</table>
<br />
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>
Poznámka:
Stejně jako v předchozím kurzu musí mít DataList v tomto kurzu povolený stav zobrazení.
ItemTemplate
V aplikaci používám dvě nové třídy CSS, které SupplierPropertyValue
byly přidány do Styles.css
třídy a nakonfigurovány tak, SupplierPropertyLabel
aby používaly stejné nastavení stylu jako ProductPropertyLabel
třídy CSS a ProductPropertyValue
CSS třídy.
.ProductPropertyLabel, .SupplierPropertyLabel
{
font-weight: bold;
text-align: right;
}
.ProductPropertyValue, .SupplierPropertyValue
{
padding-right: 35px;
}
Po provedení těchto změn navštivte tuto stránku v prohlížeči. Jak ukazuje obrázek 5, každá položka DataList zobrazuje název dodavatele jako text a používá textová pole k zobrazení adresy, města a země/oblasti.
Obrázek 5: Každý dodavatel v seznamu dat je upravitelný (kliknutím zobrazíte obrázek s plnou velikostí)
Krok 2: Přidání tlačítka Aktualizovat vše
Zatímco každý dodavatel na obrázku 5 má pole adresa, město a země/oblast zobrazená v textovém poli, aktuálně není k dispozici tlačítko Aktualizovat. Místo tlačítka Aktualizovat na položku s plně upravitelnými datovými seznamy na stránce je obvykle jediné tlačítko Aktualizovat vše, které po kliknutí aktualizuje všechny záznamy v seznamu DataList. Pro účely tohoto kurzu přidáme dvě tlačítka Aktualizovat vše – jedno v horní části stránky a jedno v dolní části (i když kliknutí na jedno tlačítko bude mít stejný efekt).
Začněte přidáním ovládacího prvku Button Web nad DataList a nastavte jeho ID
vlastnost na UpdateAll1
. Dále přidejte druhý ovládací prvek Web tlačítka pod DataList a nastavte jeho ID
na UpdateAll2
. Text
Nastavte vlastnosti dvou tlačítek tak, aby aktualizovaly vše. Nakonec vytvořte obslužné rutiny událostí pro obě události Tlačítka Click
. Místo duplikování logiky aktualizace v každém obslužných rutin událostí, pojďme refaktorovat tuto logiku na třetí metodu, UpdateAllSupplierAddresses
přičemž obslužné rutiny událostí jednoduše vyvolá tuto třetí metodu.
Protected Sub UpdateAll1_Click(sender As Object, e As EventArgs) _
Handles UpdateAll1.Click
UpdateAllSupplierAddresses()
End Sub
Protected Sub UpdateAll2_Click(sender As Object, e As EventArgs) _
Handles UpdateAll2.Click
UpdateAllSupplierAddresses()
End Sub
Private Sub UpdateAllSupplierAddresses()
' TODO: Write code to update _all_ of the supplier addresses in the DataList
End Sub
Obrázek 6 znázorňuje stránku po přidání tlačítek Aktualizovat vše.
Obrázek 6: Na stránku byly přidány dvě tlačítka pro aktualizaci všech (kliknutím zobrazíte obrázek v plné velikosti).
Krok 3: Aktualizace informací o adrese všech dodavatelů
Se všemi položkami DataList s, které zobrazují rozhraní pro úpravy a s přidáním tlačítek Aktualizovat vše, vše, co zbývá, píše kód pro provedení dávkové aktualizace. Konkrétně musíme procházet položky DataList s a volat metodu SuppliersBLL
třídy pro UpdateSupplierAddress
každou z nich.
K kolekci DataListItem
instancí, které make-up DataList lze získat přístup prostřednictvím DataList s Items
vlastnost. S odkazem na objekt DataListItem
můžeme získat odpovídající SupplierID
z DataKeys
kolekce a programově odkazovat na webové ovládací prvky TextBox v rámci ItemTemplate
následujícího kódu ukazuje:
Private Sub UpdateAllSupplierAddresses()
' Create an instance of the SuppliersBLL class
Dim suppliersAPI As New SuppliersBLL()
' Iterate through the DataList's items
For Each item As DataListItem In Suppliers.Items
' Get the supplierID from the DataKeys collection
Dim supplierID As Integer = Convert.ToInt32(Suppliers.DataKeys(item.ItemIndex))
' Read in the user-entered values
Dim address As TextBox = CType(item.FindControl("Address"), TextBox)
Dim city As TextBox = CType(item.FindControl("City"), TextBox)
Dim country As TextBox = CType(item.FindControl("Country"), TextBox)
Dim addressValue As String = Nothing, _
cityValue As String = Nothing, _
countryValue As String = Nothing
If address.Text.Trim().Length > 0 Then
addressValue = address.Text.Trim()
End If
If city.Text.Trim().Length > 0 Then
cityValue = city.Text.Trim()
End If
If country.Text.Trim().Length > 0 Then
countryValue = country.Text.Trim()
End If
' Call the SuppliersBLL class's UpdateSupplierAddress method
suppliersAPI.UpdateSupplierAddress _
(supplierID, addressValue, cityValue, countryValue)
Next
End Sub
Když uživatel klikne na jedno z tlačítek Update All, UpdateAllSupplierAddresses
metoda iteruje každý DataListItem
v Suppliers
DataList a volá metodu SuppliersBLL
třídy s UpdateSupplierAddress
předáním odpovídajících hodnot. Nezadaná hodnota pro předanou adresu, město nebo zemi/oblast je hodnota Nothing
UpdateSupplierAddress
(místo prázdného řetězce), která vede k databázi NULL
pro pole podkladových záznamů.
Poznámka:
Jako vylepšení můžete chtít na stránku přidat ovládací prvek Popisek stavu Web, který po provedení dávkové aktualizace zobrazí potvrzovací zprávu.
Aktualizace pouze těch adres, které byly změněny
Algoritmus dávkové aktualizace použitý pro tento kurz volá metodu UpdateSupplierAddress
pro každého dodavatele v seznamu DataList bez ohledu na to, zda byly změněny informace o adrese. I když tyto nevidomé aktualizace obvykle nejsou problém s výkonem, můžou vést k nadbytečným záznamům, pokud auditujete změny v tabulce databáze. Pokud například pomocí triggerů zaznamenáte všechny UPDATE
položky do Suppliers
tabulky auditování, pokaždé, když uživatel klikne na tlačítko Aktualizovat vše, vytvoří se pro každého dodavatele v systému nový záznam auditu bez ohledu na to, jestli uživatel provedl nějaké změny.
Třídy ADO.NET DataTable a DataAdapter jsou navrženy tak, aby podporovaly dávkové aktualizace, kde pouze změněné, odstraněné a nové záznamy mají za následek jakoukoli komunikaci databáze. Každý řádek v tabulce DataTable má RowState
vlastnost , která označuje, zda byl řádek přidán do tabulky DataTable, odstraněn z ní, změněn nebo zůstává beze změny. Při počátečním naplnění tabulky DataTable se všechny řádky označí beze změny. Změna hodnoty libovolného sloupce řádku označí řádek jako upravený.
SuppliersBLL
Ve třídě aktualizujeme zadané informace o adrese dodavatele tak, že nejprve přečteme v jediném záznamu SuppliersDataTable
dodavatele do a pak nastavíme Address
hodnoty , City
a Country
sloupce pomocí následujícího kódu:
Public Function UpdateSupplierAddress _
(supplierID As Integer, address As String, city As String, country As String) _
As Boolean
Dim suppliers As Northwind.SuppliersDataTable = _
Adapter.GetSupplierBySupplierID(supplierID)
If suppliers.Count = 0 Then
' no matching record found, return false
Return False
Else
Dim supplier As Northwind.SuppliersRow = suppliers(0)
If address Is Nothing Then
supplier.SetAddressNull()
Else
supplier.Address = address
End If
If city Is Nothing Then
supplier.SetCityNull()
Else
supplier.City = city
End If
If country Is Nothing Then
supplier.SetCountryNull()
Else
supplier.Country = country
End If
' Update the supplier Address-related information
Dim rowsAffected As Integer = Adapter.Update(supplier)
' Return true if precisely one row was updated, otherwise false
Return rowsAffected = 1
End If
End Function
Tento kód naively přiřadí předanou adresu, město a hodnoty země/oblasti k SuppliersRow
hodnotě bez SuppliersDataTable
ohledu na to, zda se hodnoty změnily. Tyto úpravy způsobí SuppliersRow
, že vlastnost bude RowState
označena jako změněná. Když je volána metoda vrstvy Update
přístupu k datům, zjistí, že SupplierRow
byla změněna, a proto odešle UPDATE
příkaz do databáze.
Představte si ale, že jsme do této metody přidali kód, který přiřazuje pouze předanou adresu, město a hodnoty země/oblasti, pokud se liší od SuppliersRow
existujících hodnot. V případě, že adresa, město a země/oblast jsou stejné jako existující data, nebudou provedeny žádné změny a SupplierRow
hodnoty RowState
zůstanou označené jako nezměněné. Čistý výsledek je, že když je volána metoda DAL Update
, nebude provedeno žádné volání databáze, protože SuppliersRow
nebylo změněno.
Pokud chcete tuto změnu provést, nahraďte příkazy, které nevidomě přiřazují předanou adresu, město a hodnoty země/oblasti následujícím kódem:
' Only assign the values to the SupplierRow's column values if they differ
If address Is Nothing AndAlso Not supplier.IsAddressNull() Then
supplier.SetAddressNull()
ElseIf (address IsNot Nothing AndAlso supplier.IsAddressNull) _
OrElse (Not supplier.IsAddressNull() AndAlso _
String.Compare(supplier.Address, address) <> 0) Then
supplier.Address = address
End If
If city Is Nothing AndAlso Not supplier.IsCityNull() Then
supplier.SetCityNull()
ElseIf (city IsNot Nothing AndAlso supplier.IsCityNull) _
OrElse (Not supplier.IsCityNull() AndAlso _
String.Compare(supplier.City, city) <> 0) Then
supplier.City = city
End If
If country Is Nothing AndAlso Not supplier.IsCountryNull() Then
supplier.SetCountryNull()
ElseIf (country IsNot Nothing AndAlso supplier.IsCountryNull) _
OrElse (Not supplier.IsCountryNull() AndAlso _
String.Compare(supplier.Country, country) <> 0) Then
supplier.Country = country
End If
S tímto přidaným kódem metoda DAL Update
odešle UPDATE
příkaz do databáze pouze pro ty záznamy, jejichž hodnoty související s adresou se změnily.
Případně bychom mohli sledovat, jestli mezi předanými poli adresy a databázovými daty existují nějaké rozdíly, a pokud neexistují žádné, stačí obejít volání metody DAL s Update
. Tento přístup funguje dobře, pokud používáte přímou metodu DATABÁZE, protože přímá metoda databáze není předána SuppliersRow
instanci, jejíž RowState
lze zkontrolovat, zda je volání databáze skutečně potřeba.
Poznámka:
Při každém UpdateSupplierAddress
vyvolání metody se do databáze provede volání, které načte informace o aktualizovaném záznamu. Pokud dojde k nějakým změnám dat, provede se další volání databáze pro aktualizaci řádku tabulky. Tento pracovní postup lze optimalizovat vytvořením UpdateSupplierAddress
přetížení metody, která přijímá EmployeesDataTable
instanci, která má všechny změny ze BatchUpdate.aspx
stránky. Pak může provést jedno volání databáze, aby získala všechny záznamy z Suppliers
tabulky. Tyto dva sady výsledků by pak mohly být uvedeny a pouze ty záznamy, ve kterých došlo ke změnám, se dají aktualizovat.
Shrnutí
V tomto kurzu jsme viděli, jak vytvořit plně upravitelný datový seznam, což uživateli umožňuje rychle upravit informace o adrese pro více dodavatelů. Začali jsme definováním rozhraní pro úpravy webového ovládacího prvku TextBox pro adresu dodavatele, město a hodnoty země/oblasti v DataList s ItemTemplate
. Dále jsme přidali tlačítka Aktualizovat vše nad a pod DataList. Jakmile uživatel provede změny a klikne na jedno z tlačítek Update All, DataListItem
zobrazí se výčet s a provede se volání SuppliersBLL
metody třídy UpdateSupplierAddress
.
Šť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 Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.
Zvláštní díky
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí recenzenti tohoto kurzu byli Zack Jones a Ken Pespisa. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.