Sdílet prostřednictvím


Provádění dávkových aktualizací (VB)

Scott Mitchell

Stáhnout PDF

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).

Každou položku v plně upravitelném seznamu dat lze upravit.

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.

Vytvoření nového objektu 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).

Načtení informací o dodavateli pomocí metody GetSuppliers()

Obrázek 3: Načtení informací o dodavateli pomocí GetSuppliers() metody (kliknutím zobrazíte obrázek s plnou velikostí)

Na kartě UPDATE nastavte rozevírací seznam na hodnotu (Žádné).

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é SupplierPropertyValuebyly 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.

Každý dodavatel v seznamu DataList je upravitelný.

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, UpdateAllSupplierAddressespř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.

Na stránku byly přidány dvě tlačítka Pro aktualizaci všech

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 DataListItemmůž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 Addresshodnoty , Citya 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.