Sdílet prostřednictvím


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

Scott Mitchell

Stáhnout PDF

Kliknutím na tlačítko Aktualizovat vše na stránce se dozvíte, jak vytvořit plně upravitelný datový seznam, ve kterém jsou všechny jeho položky v režimu úprav a jejichž hodnoty se dají uložit.

Úvod

V předchozím kurzu jsme se zabývali tím, jak vytvořit DataList na úrovni položky. Podobně jako u standardního upravitelného objektu GridView obsahovala každá položka v Seznamu dat tlačítko Upravit, které by po kliknutí na položku bylo upravitelné. I když tyto úpravy na úrovni položek fungují dobře u dat, která se aktualizují jenom občas, některé 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, provést změny a u každého z nich kliknout na Aktualizovat, může množství kliknutí omezit jeho produktivitu. V takových situacích je lepší poskytnout plně upravitelný datový seznam, kde jsou všechny jeho položky v režimu úprav a jehož hodnoty lze 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 seznamu dat je možné upravit (kliknutím zobrazíte obrázek v plné velikosti).

V tomto kurzu prozkoumáme, jak uživatelům umožnit aktualizovat informace o dodavatelích adres pomocí plně upravitelného seznamu DataList.

Krok 1: Vytvoření upravitelného uživatelského rozhraní v DataList s ItemTemplate

V předchozím kurzu, kde jsme vytvořili standardní upravitelný datový seznam na úrovni položek, jsme použili dvě šablony:

  • ItemTemplate obsahoval 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 se (pokud existuje) vykresluje pomocí EditItemTemplate. Konkrétně se DataListItem hodnota, jejíž ItemIndex hodnota odpovídá vlastnosti DataList s EditItemIndex , vykresluje pomocí EditItemTemplate. Tento model funguje dobře, když lze současně upravovat jenom jednu položku, ale při vytváření plně upravitelného seznamu Dat se rozpadá.

Pro plně upravitelný DataList chceme, aby se všechny s DataListItem vykreslovat pomocí upravitelného rozhraní. Nejjednodušším způsobem, jak toho dosáhnout, je definovat upravitelné rozhraní v .ItemTemplate Pro úpravu informací o adrese dodavatele obsahuje upravitelné rozhraní název dodavatele jako text a pak 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 zvolte přidání nového ovládacího prvku ObjectDataSource s názvem SuppliersDataSource.

Vytvoření nového objektuDataSource s názvem SuppliersDataSource

Obrázek 2: Vytvoření nového objektuDataSource s názvem SuppliersDataSource (kliknutím zobrazíte obrázek v plné velikosti)

Nakonfigurujte ObjectDataSource tak, aby načítal data pomocí SuppliersBLL metody třídy s GetSuppliers() (viz Obrázek 3). Stejně jako v předchozím kurzu nebudeme aktualizovat informace o dodavateli prostřednictvím ObjectDataSource, ale 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 GetSuppliers() pomocí metody (kliknutím zobrazíte obrázek v plné velikosti)

Nastavte seznam Drop-Down na (Žádný) na kartě AKTUALIZOVAT.

Obrázek 4: Nastavení seznamu Drop-Down na (Žádný) na kartě AKTUALIZACE (kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce Visual Studio automaticky vygeneruje dataList pro ItemTemplate zobrazení všech datových polí vrácených zdrojem dat v ovládacím prvku Label Web. Tuto šablonu musíme upravit tak, aby místo toho poskytovala rozhraní pro úpravy. Objekt ItemTemplate lze přizpůsobit prostřednictvím Designer pomocí možnosti Upravit šablony z inteligentní značky DataList nebo přímo prostřednictvím deklarativní syntaxe.

Udělejte si chvilku a vytvořte rozhraní pro úpravy, které zobrazí jméno dodavatele jako text, ale bude obsahovat textová pole pro adresu dodavatele, město a zemi/oblast. 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 datový seznam v tomto kurzu povolený stav zobrazení.

V části ItemTemplate Používám dvě nové třídy CSS, SupplierPropertyLabel a SupplierPropertyValue, které byly přidány do Styles.css třídy a nakonfigurovány tak, aby používaly stejné nastavení stylu jako ProductPropertyLabel třídy a ProductPropertyValue CSS.

.ProductPropertyLabel, .SupplierPropertyLabel
{
    font-weight: bold;
    text-align: right;
}
.ProductPropertyValue, .SupplierPropertyValue
{
    padding-right: 35px;
}

Po provedení těchto změn přejděte na tuto stránku prostřednictvím prohlížeče. Jak znázorňuje 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 DataList je upravitelný (kliknutím zobrazíte obrázek v plné velikosti)

Krok 2: Přidání tlačítka Aktualizovat vše

I když má každý dodavatel na obrázku 5 v textovém poli zobrazená pole adresa, město a země/oblast, momentálně není k dispozici tlačítko Aktualizovat. Místo tlačítka Aktualizovat pro každou položku s plně upravitelnými položkami DataLists je obvykle na stránce jedno 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 dole (i když kliknutí na jedno z těchto tlačítek bude mít stejný účinek).

Začněte přidáním webového ovládacího prvku Button (Tlačítko) nad DataList a nastavte jeho ID vlastnost na UpdateAll1. Dále přidejte druhý webový ovládací prvek Button (Webové tlačítko) pod DataList a nastavte ho ID na UpdateAll2. Text Nastavte vlastnosti těchto dvou tlačítek na Aktualizovat vše. Nakonec vytvořte obslužné rutiny událostí pro obě události tlačítka Click . Místo duplikování logiky aktualizace v jednotlivých obslužných rutinách událostí pojďme tuto logiku refaktorovat na třetí metodu, s tím, UpdateAllSupplierAddressesže obslužné rutiny událostí jednoduše vyvolávají tuto třetí metodu.

protected void UpdateAll1_Click(object sender, EventArgs e)
{
    UpdateAllSupplierAddresses();
}
protected void UpdateAll2_Click(object sender, EventArgs e)
{
    UpdateAllSupplierAddresses();
}
private void UpdateAllSupplierAddresses()
{
    // TODO: Write code to update _all_ of the supplier addresses in the DataList
}

Obrázek 6 znázorňuje stránku po přidání tlačítek Aktualizovat vše.

Na stránku byla přidána dvě tlačítka Aktualizovat všechna

Obrázek 6: Na stránku byla přidána dvě tlačítka Aktualizovat všechny (kliknutím zobrazíte obrázek v plné velikosti)

Krok 3: Aktualizace informací o adrese všech dodavatelů

Se všemi položkami DataList zobrazují rozhraní pro úpravy a s přidáním tlačítek Aktualizovat vše, vše, co zbývá, je napsání kódu pro provedení dávkové aktualizace. Konkrétně potřebujeme projít položky Třídy s a volat metodu SuppliersBLL třídy s UpdateSupplierAddress pro každou z nich.

Ke kolekci DataListItem instancí, které jsou součástí objektu DataList, je možné přistupovat prostřednictvím vlastnosti DataList sItems. S odkazem na DataListItemobjekt můžeme získat odpovídající SupplierID z DataKeys kolekce a programově odkazovat na ovládací prvky TextBox Web v rámci objektu ItemTemplate , jak ukazuje následující kód:

private void UpdateAllSupplierAddresses()
{
    // Create an instance of the SuppliersBLL class
    SuppliersBLL suppliersAPI = new SuppliersBLL();
    // Iterate through the DataList's items
    foreach (DataListItem item in Suppliers.Items)
    {
        // Get the supplierID from the DataKeys collection
        int supplierID = Convert.ToInt32(Suppliers.DataKeys[item.ItemIndex]);
        // Read in the user-entered values
        TextBox address = (TextBox)item.FindControl("Address");
        TextBox city = (TextBox)item.FindControl("City");
        TextBox country = (TextBox)item.FindControl("Country");
        string addressValue = null, cityValue = null, countryValue = null;
        if (address.Text.Trim().Length > 0)
            addressValue = address.Text.Trim();
        if (city.Text.Trim().Length > 0)
              cityValue = city.Text.Trim();
        if (country.Text.Trim().Length > 0)
            countryValue = country.Text.Trim();
        // Call the SuppliersBLL class's UpdateSupplierAddress method
        suppliersAPI.UpdateSupplierAddress
            (supplierID, addressValue, cityValue, countryValue);
    }
}

Když uživatel klikne na jedno z tlačítek Aktualizovat vše, UpdateAllSupplierAddresses metoda prochází všechna DataListItem tlačítka v Suppliers DataList a volá metodu SuppliersBLL třídy s UpdateSupplierAddress a předá odpovídající hodnoty. Nezadaná hodnota pro adresu, město nebo zemi/oblast je hodnota Nothing do (nikoli prázdný řetězec), což vede k UpdateSupplierAddress databázi NULL pro pole podkladových záznamů.

Poznámka

Pro vylepšení můžete chtít na stránku přidat ovládací prvek Status Label Web, který po provedení dávkové aktualizace poskytuje potvrzovací zprávu.

Aktualizují se jenom adresy, které byly změněny.

Algoritmus dávkové aktualizace použitý v tomto kurzu 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 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. Pokud například pomocí aktivačních událostí 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, kdy 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 změněný.

SuppliersBLL Ve třídě aktualizujeme zadané informace o adrese dodavatele tak, že nejprve přečteme jeden záznam dodavatele do SuppliersDataTable a pak nastavíme Addresshodnoty sloupce , Citya Country pomocí následujícího kódu:

public bool UpdateSupplierAddress
    (int supplierID, string address, string city, string country)
{
    Northwind.SuppliersDataTable suppliers =
        Adapter.GetSupplierBySupplierID(supplierID);
    if (suppliers.Count == 0)
        // no matching record found, return false
        return false;
    else
    {
        Northwind.SuppliersRow supplier = suppliers[0];
        if (address == null)
            supplier.SetAddressNull();
        else
            supplier.Address = address;
        if (city == null)
            supplier.SetCityNull();
        else
            supplier.City = city;
        if (country == null)
            supplier.SetCountryNull();
        else
            supplier.Country = country;
        // Update the supplier Address-related information
        int rowsAffected = Adapter.Update(supplier);
        // Return true if precisely one row was updated,
        // otherwise false
        return rowsAffected == 1;
    }
}

Tento kód naivně přiřadí předané hodnoty adresy, města a země/oblasti k SuppliersRow hodnotě SuppliersDataTable v bez ohledu na to, jestli se hodnoty změnily. Tyto úpravy způsobí, že SuppliersRow vlastnost s RowState se označí jako změněná. Při zavolání metody Data Access Layer Update se zobrazí, že SupplierRow došlo k úpravě, 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řadí předané hodnoty adresy, města a země/oblasti jenom v případě, že se liší od SuppliersRow existujících hodnot. V případě, že jsou adresa, město a země/oblast stejné jako stávající data, neprovedou se žádné změny a SupplierRowRowState hodnoty zůstanou označené jako nezměněné. Čistý výsledek je, že při volání metody DAL s Update se neprovedou žádné volání databáze, protože SuppliersRow nebyl změněn.

Pokud chcete tuto změnu provést, nahraďte příkazy, které předané hodnoty adresy, města a země/oblasti slepě přiřazují, následujícím kódem:

// Only assign the values to the SupplierRow's column values if they differ
if (address == null && !supplier.IsAddressNull())
    supplier.SetAddressNull();
else if ((address != null && supplier.IsAddressNull()) ||
         (!supplier.IsAddressNull() &&
         string.Compare(supplier.Address, address) != 0))
    supplier.Address = address;
if (city == null && !supplier.IsCityNull())
    supplier.SetCityNull();
else if ((city != null && supplier.IsCityNull()) ||
         (!supplier.IsCityNull() && string.Compare(supplier.City, city) != 0))
    supplier.City = city;
if (country == null && !supplier.IsCountryNull())
    supplier.SetCountryNull();
else if ((country != null && supplier.IsCountryNull()) ||
         (!supplier.IsCountryNull() &&
         string.Compare(supplier.Country, country) != 0))
    supplier.Country = country;

S tímto přidaným kódem metoda DAL s Update odešle UPDATE do databáze příkaz pouze pro ty záznamy, jejichž hodnoty související s adresou se změnily.

Případně bychom mohli sledovat, jestli jsou mezi poli předané adresy a databázovými daty nějaké rozdíly, a pokud žádné neexistují, jednoduše 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 kontrolu lze zkontrolovat, zda je volání databáze skutečně potřeba.

Poznámka

Při každém vyvolání UpdateSupplierAddress metody se provede volání databáze za účelem načtení informací o aktualizovaném záznamu. Pokud pak dojde k nějakým změnám v datech, provede se další volání databáze, které aktualizuje řádek tabulky. Tento pracovní postup je možné optimalizovat vytvořením UpdateSupplierAddress přetížení metody, které přijímá EmployeesDataTable instanci, která obsahuje všechny změny ze BatchUpdate.aspx stránky. Pak může provést jedno volání databáze, aby se získaly všechny záznamy z Suppliers tabulky. Tyto dvě sady výsledků by se pak daly vyčíslit a aktualizovat se dají jenom ty záznamy, ve kterých došlo ke změnám.

Souhrn

V tomto kurzu jsme viděli, jak vytvořit plně upravitelný seznam dat, který uživateli umožňuje rychle upravit informace o adrese pro více dodavatelů. Začali jsme definováním rozhraní pro úpravy ovládacího prvku TextBox Web pro hodnoty adresy dodavatele, města a země/oblasti v DataList s ItemTemplate. Dále jsme nad a pod dataList přidali tlačítka Aktualizovat vše. Jakmile uživatel provede změny a klikne na jedno z tlačítek Aktualizovat vše, DataListItem zobrazí se výčet s a provede se SuppliersBLL volání metody třídy s UpdateSupplierAddress .

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 Zack Jones a Ken Pespisa. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.