Sdílet prostřednictvím


Implementace optimistického řízení souběžnosti ovládacím prvkem SqlDataSource (C#)

Scott Mitchell

Stáhnout PDF

V tomto kurzu si projdeme základy optimistického řízení souběžnosti a pak prozkoumáme, jak ho implementovat pomocí ovládacího prvku SqlDataSource.

Úvod

V předchozím kurzu jsme prozkoumali, jak přidat funkce vkládání, aktualizace a odstraňování do ovládacího prvku SqlDataSource. Stručně řečeno, abychom mohli tyto funkce poskytnout, museli jsme zadat odpovídající INSERTUPDATEpříkaz , nebo DELETE SQL ve vlastnostech ovládacích InsertCommandUpdateCommandprvků , nebo DeleteCommand spolu s příslušnými parametry v InsertParameterskolekcích , UpdateParametersa DeleteParameters . I když je možné tyto vlastnosti a kolekce zadat ručně, tlačítko Průvodce konfigurací zdroje dat s rozšířeným tlačítkem nabízí zaškrtávací políčko Generovat INSERTpříkazy , UPDATEa DELETE , které automaticky vytvoří tyto příkazy na SELECT základě příkazu.

Spolu se zaškrtávacím políček Generovat INSERTUPDATEpříkazy , a DELETE obsahuje dialogové okno Rozšířené možnosti generování SQL možnost Použít optimistickou souběžnost (viz Obrázek 1). Při zaškrtnutí se klauzule v automaticky vygenerovaných UPDATE příkazech a DELETE upraví tak, aby provedly aktualizaci nebo odstranění pouze v případě, WHERE že se podkladová data databáze od posledního načtení dat uživatelem do mřížky nezměnila.

Podporu optimistické souběžnosti můžete přidat v dialogovém okně Rozšířené možnosti generování SQL.

Obrázek 1: Podporu optimistické souběžnosti můžete přidat v dialogovém okně Rozšířené možnosti generování SQL.

V kurzu Implementace optimistické souběžnosti jsme prozkoumali základy řízení optimistické souběžnosti a postup jeho přidání do ObjectDataSource. V tomto kurzu se podíváme na základy optimistického řízení souběžnosti a pak prozkoumáme, jak ho implementovat pomocí SqlDataSource.

Rekapitulace optimistické souběžnosti

U webových aplikací, které umožňují více souběžným uživatelům upravovat nebo odstraňovat stejná data, existuje možnost, že jeden uživatel může omylem přepsat jiné změny. V kurzu Implementace optimistické souběžnosti jsem uvedl následující příklad:

Představte si, že dva uživatelé, Jisun a Sam, navštívili stránku v aplikaci, která návštěvníkům umožňovala aktualizovat a odstraňovat produkty prostřednictvím ovládacího prvku GridView. Oba kliknou na tlačítko Upravit pro Chai přibližně ve stejnou dobu. Jisun změní název produktu na Chai Tea a klikne na tlačítko Aktualizovat. Čistý výsledek je příkaz UPDATE , který se odešle do databáze, který nastaví všechna aktualizovatelná pole produktu (i když Jisun aktualizoval pouze jedno pole, ProductName). V tomto okamžiku má databáze pro tento konkrétní produkt hodnoty Chai Tea, kategorii Nápoje, dodavatele exotické kapaliny a tak dále. Na obrazovce GridView na Sam s se však stále zobrazuje název produktu v upravitelném řádku GridView jako Chai. Několik sekund po potvrzení změn Jisun sam aktualizuje kategorii na Condimenty a klikne na Aktualizovat. Výsledkem je UPDATE příkaz odeslaný do databáze, který nastaví název produktu na Chai, CategoryID odpovídající ID kategorie Condiments atd. Jisun s změny názvu produktu byly přepsány.

Tuto interakci znázorňuje obrázek 2.

Když dva uživatelé současně aktualizují záznam, může dojít k tomu, že jeden uživatel může přepsat ostatní uživatele.

Obrázek 2: Když dva uživatelé současně aktualizují záznam, je možné, že jeden uživatel může změnit ostatní uživatele (kliknutím zobrazíte obrázek v plné velikosti)

Aby se zabránilo tomuto scénáři, musí být implementována forma řízení souběžnosti . Optimistická souběžnost , na kterou se zaměřuje tento kurz, funguje s předpokladem, že i když občas může docházet ke konfliktům souběžnosti, v drtivé většině případů k takovým konfliktům nedojde. Proto pokud dojde ke konfliktu, optimistické řízení souběžnosti jednoduše informuje uživatele, že jeho změny nelze uložit, protože jiný uživatel upravil stejná data.

Poznámka

U aplikací, u kterých se předpokládá, že dojde k mnoha konfliktům souběžnosti nebo pokud takové konflikty nejsou přípustné, je možné místo toho použít pesimistické řízení souběžnosti. Podrobnější diskuzi o pesimistickém řízení souběžnosti najdete v kurzu Implementace optimistické souběžnosti .

Optimistické řízení souběžnosti funguje tak, že zajišťuje, aby aktualizovaný nebo odstraněný záznam měl stejné hodnoty jako při zahájení procesu aktualizace nebo odstraňování. Například při kliknutí na tlačítko Upravit v upravitelném objektu GridView se hodnoty záznamů načtou z databáze a zobrazí se v textových polích a dalších webových ovládacích prvcích. Tyto původní hodnoty jsou uloženy objektem GridView. Později, poté, co uživatel provede změny a klikne na tlačítko Aktualizovat, UPDATE musí použitý příkaz vzít v úvahu původní hodnoty a nové hodnoty a aktualizovat podkladový záznam databáze pouze v případě, že původní hodnoty, které uživatel začal upravovat, jsou shodné s hodnotami, které jsou stále v databázi. Obrázek 3 znázorňuje tuto posloupnost událostí.

Aby byla aktualizace nebo odstranění úspěšná, musí být původní hodnoty rovny aktuálním hodnotám databáze.

Obrázek 3: Pro úspěšné aktualizace nebo odstranění musí být původní hodnoty stejné jako aktuální hodnoty databáze (kliknutím zobrazíte obrázek v plné velikosti)

Existují různé přístupy k implementaci optimistické souběžnosti (podívejte se na řadu možností v článku Optimistic concurrency v článku Peter A. Bromberg). Technika používaná sqldatasource (stejně jako ADO.NET typed dataSets používaných v naší vrstvě přístupu k datům) rozšiřuje klauzuli WHERE tak, aby zahrnovala porovnání všech původních hodnot. Následující UPDATE příkaz například aktualizuje název a cenu produktu pouze v případě, že aktuální hodnoty databáze jsou rovny hodnotám, které byly původně načteny při aktualizaci záznamu v GridView. Parametry @ProductName a @UnitPrice obsahují nové hodnoty zadané uživatelem, zatímco @original_ProductName a @original_UnitPrice obsahují hodnoty, které byly původně načteny do GridView při kliknutí na tlačítko Upravit:

UPDATE Products SET
    ProductName = @ProductName,
    UnitPrice = @UnitPrice
WHERE
    ProductID = @original_ProductID AND
    ProductName = @original_ProductName AND
    UnitPrice = @original_UnitPrice

Jak uvidíme v tomto kurzu, povolení optimistického řízení souběžnosti pomocí SqlDataSource je stejně jednoduché jako zaškrtnutí políčka.

Krok 1: Vytvoření zdroje SqlDataSource, který podporuje optimistickou souběžnost

Začněte otevřením OptimisticConcurrency.aspx stránky ze SqlDataSource složky. Přetáhněte ovládací prvek SqlDataSource ze sady nástrojů do Designer a jeho vlastnost na ProductsDataSourceWithOptimisticConcurrencyhodnotu ID . Potom klikněte na odkaz Konfigurovat zdroj dat z inteligentní značky ovládacího prvku. Na první obrazovce průvodce zvolte, jestli chcete pracovat s NORTHWINDConnectionString a klikněte na Další.

Volba práce s řetězcem NORTHWINDConnectionString

Obrázek 4: Volba pro práci s obrázkem NORTHWINDConnectionString (kliknutím zobrazíte obrázek v plné velikosti)

V tomto příkladu přidáme Objekt GridView, který uživatelům umožní upravovat Products tabulku. Proto na obrazovce Konfigurovat příkaz Select zvolte Products tabulku z rozevíracího seznamu a vyberte ProductIDsloupce , ProductName, UnitPricea Discontinued , jak je znázorněno na obrázku 5.

Z tabulky Products (Produkty) vraťte sloupce ProductID (ID produktu), ProductName (NázevProduktu), UnitPrice (Cena za jednotku) a (Ukončeno).

Obrázek 5: Z Products tabulky vrátíte ProductIDsloupce , ProductName, UnitPricea a Discontinued (kliknutím zobrazíte obrázek v plné velikosti)

Po výběru sloupců kliknutím na tlačítko Upřesnit zobrazíte dialogové okno Rozšířené možnosti generování SQL. Zaškrtněte políčka Generovat INSERTpříkazy , UPDATEa DELETE a Použít optimistickou souběžnost a klikněte na OK (snímek obrazovky najdete na obrázku 1). Dokončete průvodce kliknutím na Další a pak na Dokončit.

Po dokončení průvodce Konfigurací zdroje dat chvíli prozkoumejte výsledné DeleteCommand vlastnosti DeleteParameters a UpdateCommand kolekce aUpdateParameters. Nejjednodušší způsob, jak to udělat, je kliknout na kartu Zdroj v levém dolním rohu a zobrazit deklarativní syntaxi stránky. Tam najdete UpdateCommand hodnotu:

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     [UnitPrice] = @original_UnitPrice AND
     [Discontinued] = @original_Discontinued

Se sedmi parametry v kolekci UpdateParameters :

<asp:SqlDataSource ID="ProductsDataSourceWithOptimisticConcurrency"
    runat="server" ...>
    <DeleteParameters>
      ...
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </UpdateParameters>
    ...
</asp:SqlDataSource>

DeleteCommand Podobně by vlastnost a DeleteParameters kolekce měly vypadat takto:

DELETE FROM [Products]
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     [UnitPrice] = @original_UnitPrice AND
     [Discontinued] = @original_Discontinued
<asp:SqlDataSource ID="ProductsDataSourceWithOptimisticConcurrency"
    runat="server" ...>
    <DeleteParameters>
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </DeleteParameters>
    <UpdateParameters>
        ...
    </UpdateParameters>
    ...
</asp:SqlDataSource>

Kromě rozšíření WHERE klauzulí UpdateCommand vlastností a DeleteCommand (a přidání dalších parametrů do příslušných kolekcí parametrů) upravíte výběrem možnosti Použít optimistickou souběžnost dvě další vlastnosti:

Když datový web ovládací prvek vyvolá SqlDataSource s Update() nebo Delete() metodu, předává původní hodnoty. Pokud je vlastnost SqlDataSource s ConflictDetection nastavená na CompareAllValues, tyto původní hodnoty se přidají do příkazu. Vlastnost OldValuesParameterFormatString poskytuje vzor pojmenování použitý pro tyto parametry původní hodnoty. Průvodce konfigurovat zdroj dat používá original_{0} a pojmenovává každý původní parametr ve UpdateCommand vlastnostech a DeleteCommandUpdateParameters kolekcích a DeleteParameters odpovídajícím způsobem.

Poznámka

Vzhledem k tomu, že nepoužíváme funkce vkládání ovládacích prvků SqlDataSource, můžete odebrat vlastnost a její InsertParameters kolekciInsertCommand.

Správné zpracováníNULLhodnot

Rozšířené UPDATE příkazy a DELETE automaticky generované průvodcem Konfigurovat zdroj dat při použití optimistické souběžnosti bohužel nefungují se záznamy obsahujícími NULL hodnoty. Pokud chcete zjistit důvod, podívejte se na naše sqldatasource:UpdateCommand

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     [UnitPrice] = @original_UnitPrice AND
     [Discontinued] = @original_Discontinued

Sloupec UnitPrice v tabulce Products může obsahovat NULL hodnoty. Pokud má NULL konkrétní záznam hodnotu pro UnitPrice, WHERE část [UnitPrice] = @original_UnitPrice klauzule se vždy vyhodnotí jako Nepravda, protože NULL = NULL vždy vrátí hodnotu False. Záznamy obsahující hodnoty proto nelze upravovat ani odstraňovat, protože UPDATE klauzule příkazů a DELETE nevrátí žádné řádkyWHERE, které NULL by bylo možné aktualizovat nebo odstranit.

Poznámka

Tato chyba byla poprvé nahlášena společnosti Microsoft v červnu 2004 v sqldatasource generuje nesprávné příkazy SQL a je údajně naplánováno, aby byla opravena v příští verzi ASP.NET.

Abychom tento problém vyřešili, musíme ručně aktualizovat WHERE klauzule ve vlastnostech a UpdateCommandDeleteCommand pro všechny sloupce, které můžou obsahovat NULL hodnoty. Obecně platí, že změňte [ColumnName] = @original_ColumnName na:

(
   ([ColumnName] IS NULL AND @original_ColumnName IS NULL)
     OR
   ([ColumnName] = @original_ColumnName)
)

Tuto změnu lze provést přímo prostřednictvím deklarativních značek, prostřednictvím možností UpdateQuery nebo DeleteQuery z okno Vlastnosti nebo prostřednictvím karet UPDATE a DELETE v možnosti Zadat vlastní příkaz SQL nebo uloženou proceduru v průvodci Konfigurovat zdroj dat. Znovu platí, že tato úprava musí být provedena pro každý sloupec v klauzuli UpdateCommand a DeleteCommand s WHERE , který může obsahovat NULL hodnoty.

Použití tohoto příkladu má za následek následující změněné UpdateCommand hodnoty a DeleteCommand hodnoty:

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
        OR ([UnitPrice] = @original_UnitPrice)) AND
     [Discontinued] = @original_Discontinued
DELETE FROM [Products]
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
        OR ([UnitPrice] = @original_UnitPrice)) AND
     [Discontinued] = @original_Discontinued

Krok 2: Přidání objektu GridView s možnostmi úprav a odstranění

S SqlDataSource nakonfigurovaný tak, aby podporoval optimistickou souběžnost, vše, co zbývá, je přidat datový webový ovládací prvek na stránku, který využívá tento řízení souběžnosti. Pro účely tohoto kurzu přidáme Objekt GridView, který poskytuje funkce pro úpravy i odstranění. Chcete-li toho dosáhnout, přetáhněte objekt GridView z panelu nástrojů do Designer a nastavte jeho ID hodnotu na Products. Z inteligentní značky GridView s vytvořte vazbu k ovládacímu ProductsDataSourceWithOptimisticConcurrency prvku SqlDataSource přidanému v kroku 1. Nakonec zaškrtněte možnosti Povolit úpravy a Povolit odstranění z inteligentní značky.

Vytvoření vazby objektu GridView na SqlDataSource a povolení úprav a odstranění

Obrázek 6: Vytvoření vazby objektu GridView k SqlDataSource a povolení úprav a odstranění (kliknutím zobrazíte obrázek v plné velikosti)

Po přidání Objekt GridView nakonfigurujte jeho vzhled odebráním ProductID BoundField, změnou ProductName vlastnosti BoundField na HeaderText Product a aktualizací UnitPrice BoundField tak, aby jeho HeaderText vlastnost byla jednoduše Price. V ideálním případě bychom vylepšili rozhraní pro úpravy tak, aby obsahovalo RequiredFieldValidator pro ProductName hodnotu a CompareValidator pro UnitPrice hodnotu (aby se zajistilo, že se jedná o správně formátovanou číselnou hodnotu). Podrobnější informace o přizpůsobení rozhraní pro úpravy objektu GridView najdete v kurzu Přizpůsobení rozhraní pro úpravy dat .

Poznámka

Stav zobrazení GridView musí být povolen, protože původní hodnoty předané z GridView sqlDataSource jsou uloženy ve stavu zobrazení.

Po provedení těchto úprav gridview deklarativní značky GridView a SqlDataSource by měly vypadat nějak takto:

<asp:SqlDataSource ID="ProductsDataSourceWithOptimisticConcurrency"
    runat="server" ConflictDetection="CompareAllValues"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    DeleteCommand=
        "DELETE FROM [Products]
         WHERE [ProductID] = @original_ProductID
         AND [ProductName] = @original_ProductName
         AND (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
              OR ([UnitPrice] = @original_UnitPrice))
         AND [Discontinued] = @original_Discontinued"
    OldValuesParameterFormatString=
        "original_{0}"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
         FROM [Products]"
    UpdateCommand=
        "UPDATE [Products]
         SET [ProductName] = @ProductName, [UnitPrice] = @UnitPrice,
            [Discontinued] = @Discontinued
         WHERE [ProductID] = @original_ProductID
         AND [ProductName] = @original_ProductName
         AND (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL)
            OR ([UnitPrice] = @original_UnitPrice))
        AND [Discontinued] = @original_Discontinued">
    <DeleteParameters>
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_Discontinued" Type="Boolean" />
    </UpdateParameters>
</asp:SqlDataSource>
<asp:GridView ID="Products" runat="server"
    AutoGenerateColumns="False" DataKeyNames="ProductID"
    DataSourceID="ProductsDataSourceWithOptimisticConcurrency">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

Pokud chcete zobrazit řízení optimistické souběžnosti v akci, otevřete dvě okna prohlížeče a načtěte OptimisticConcurrency.aspx stránku v obou. Klikněte na tlačítka Upravit u prvního produktu v obou prohlížečích. V jednom prohlížeči změňte název produktu a klikněte na Aktualizovat. Prohlížeč se vrátí zpět a Objekt GridView se vrátí do režimu před úpravami, ve kterém se zobrazí nový název produktu pro právě upravený záznam.

V druhém okně prohlížeče změňte cenu (ale ponechte název produktu jako původní hodnotu) a klikněte na Aktualizovat. Při postbacku se mřížka vrátí do režimu před úpravami, ale změna ceny se nezaznamená. Ve druhém prohlížeči se zobrazí stejná hodnota jako u prvního, název nového produktu se starou cenou. Změny provedené v druhém okně prohlížeče byly ztraceny. Změny se navíc ztratily poměrně tiše, protože se nenašla žádná výjimka nebo zpráva, které by oznamovaly, že právě došlo k narušení souběžnosti.

Změny v druhém okně prohlížeče byly bezobslužně ztraceny.

Obrázek 7: Změny v druhém okně prohlížeče byly bezobslužně ztraceny (kliknutím zobrazíte obrázek v plné velikosti)

Důvodem, proč nebyly potvrzeny druhé změny prohlížeče, bylo to, že UPDATE klauzule statement s WHERE vyfiltrovala všechny záznamy, a proto neovlivnila žádné řádky. Podívejme se znovu na UPDATE příkaz :

UPDATE [Products] SET
     [ProductName] = @ProductName,
     [UnitPrice] = @UnitPrice,
     [Discontinued] = @Discontinued
WHERE
     [ProductID] = @original_ProductID AND
     [ProductName] = @original_ProductName AND
     (([UnitPrice] IS NULL AND @original_UnitPrice IS NULL) OR
        ([UnitPrice] = @original_UnitPrice)) AND
     [Discontinued] = @original_Discontinued

Když druhé okno prohlížeče aktualizuje záznam, původní název produktu zadaný v WHERE klauzuli neodpovídá existujícímu názvu produktu (protože byl změněn prvním prohlížečem). Příkaz [ProductName] = @original_ProductName proto vrátí hodnotu False a nemá vliv na UPDATE žádné záznamy.

Poznámka

Odstranění funguje stejným způsobem. Když jsou otevřená dvě okna prohlížeče, začněte úpravou daného produktu v jednom a pak uložte jeho změny. Po uložení změn v jednom prohlížeči klikněte na tlačítko Odstranit pro stejný produkt v druhém prohlížeči. Vzhledem k tomu, že původní hodnoty v DELETE klauzuli s příkazu WHERE neodpovídají, odstranění se bezobslužně nezdaří.

Z pohledu koncového uživatele v druhém okně prohlížeče se po kliknutí na tlačítko Aktualizovat mřížka vrátí do režimu před úpravami, ale změny se ztratily. Neexistuje ale žádná vizuální zpětná vazba, že by se jejich změny nezlepily. V ideálním případě, pokud dojde ke ztrátě změn uživatele v důsledku narušení souběžnosti, upozorníme uživatele a třeba mřížku ponecháme v režimu úprav. Pojďme se podívat, jak toho dosáhnout.

Krok 3: Určení, kdy došlo k narušení souběžnosti

Vzhledem k tomu, že porušení souběžnosti odmítne provedené změny, bylo by vhodné upozornit uživatele, když dojde k narušení souběžnosti. Chcete-li uživatele upozornit, přidejte do horní části stránky ovládací prvek Label Web, ConcurrencyViolationMessage jehož Text vlastnost zobrazí následující zprávu: Pokusili jste se aktualizovat nebo odstranit záznam, který byl současně aktualizován jiným uživatelem. Zkontrolujte změny provedené jiným uživatelem a pak znovu proveďte aktualizaci nebo odstraňte. Nastavte vlastnost Ovládací prvek CssClass Popisek na Warning, což je třída CSS definovaná v Styles.css , která zobrazuje text červeným, kurzívou, tučným a velkým písmem. Nakonec nastavte vlastnosti Popisky Visible a EnableViewState na false. Tím se popisek skryje s výjimkou pouze těch zpětných odeslání, u kterých jsme explicitně nastavili jeho Visible vlastnost na true.

Přidání ovládacího prvku Popisek na stránku pro zobrazení upozornění

Obrázek 8: Přidání ovládacího prvku Popisek na stránku pro zobrazení upozornění (kliknutím zobrazíte obrázek v plné velikosti)

Při provádění aktualizace nebo odstranění se gridView s RowUpdated a RowDeleted obslužné rutiny událostí aktivují poté, co ovládací prvek zdroje dat provedl požadovanou aktualizaci nebo odstranění. Z těchto obslužných rutin událostí můžeme určit, kolik řádků bylo operací ovlivněno. Pokud by to mělo vliv na nula řádků, chceme popisek ConcurrencyViolationMessage zobrazit.

Vytvořte obslužnou rutinu RowUpdated události pro události a a RowDeleted přidejte následující kód:

protected void Products_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
    if (e.AffectedRows == 0)
    {
        ConcurrencyViolationMessage.Visible = true;
        e.KeepInEditMode = true;
        // Rebind the data to the GridView to show the latest changes
        Products.DataBind();
    }
}
protected void Products_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
    if (e.AffectedRows == 0)
        ConcurrencyViolationMessage.Visible = true;
}

V obou obslužných rutinách událostí zkontrolujeme e.AffectedRows vlastnost a pokud se rovná 0, nastavíme ConcurrencyViolationMessage vlastnost Label s Visible na true. V obslužné rutině RowUpdated události také dáváme objektu GridView pokyn, aby zůstal v režimu úprav nastavením KeepInEditMode vlastnosti na hodnotu true. Přitom musíme data znovu připojit k mřížce, aby se data ostatních uživatelů načetla do rozhraní pro úpravy. Toho se dosahuje voláním GridView s DataBind() metody.

Jak ukazuje obrázek 9, u těchto dvou obslužných rutin událostí se při každém výskytu narušení souběžnosti zobrazí velmi nápadná zpráva.

Zpráva se zobrazí tváří v tvář narušení souběžnosti

Obrázek 9: Zpráva se zobrazí v pohledu na narušení souběžnosti (kliknutím zobrazíte obrázek v plné velikosti).

Souhrn

Při vytváření webové aplikace, ve které může stejná data upravovat několik souběžných uživatelů, je důležité zvážit možnosti řízení souběžnosti. Ve výchozím nastavení webové ovládací prvky ASP.NET dat a zdroje dat nepoužívají žádné řízení souběžnosti. Jak jsme viděli v tomto kurzu, implementace optimistického řízení souběžnosti pomocí zdroje SqlDataSource je relativně rychlá a snadná. SqlDataSource zpracovává většinu legí pro přidání rozšířených WHERE klauzulí do automaticky vygenerovaných UPDATE příkazů a, DELETE ale existuje několik jemností ve zpracování NULL sloupců hodnot, jak je popsáno v části Správné zpracování NULL hodnot.

Tento kurz uzavírá naše zkoumání sqldatasource. Naše zbývající kurzy se vrátí k práci s daty pomocí ObjectDataSource a vrstvené architektury.

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.