Implementace optimistického řízení souběžnosti ovládacím prvkem SqlDataSource (C#)
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í INSERT
UPDATE
příkaz , nebo DELETE
SQL ve vlastnostech ovládacích InsertCommand
UpdateCommand
prvků , nebo DeleteCommand
spolu s příslušnými parametry v InsertParameters
kolekcích , UpdateParameters
a 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 INSERT
příkazy , UPDATE
a DELETE
, které automaticky vytvoří tyto příkazy na SELECT
základě příkazu.
Spolu se zaškrtávacím políček Generovat INSERT
UPDATE
pří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.
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.
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í.
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 ProductsDataSourceWithOptimisticConcurrency
hodnotu 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ší.
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 ProductID
sloupce , ProductName
, UnitPrice
a Discontinued
, jak je znázorněno na obrázku 5.
Obrázek 5: Z Products
tabulky vrátíte ProductID
sloupce , ProductName
, UnitPrice
a 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 INSERT
příkazy , UPDATE
a 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:
ConflictDetection
Změní vlastnost zOverwriteChanges
(výchozí) naCompareAllValues
OldValuesParameterFormatString
Změní vlastnost z {0} (výchozí) na original_{0} .
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 DeleteCommand
UpdateParameters
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íNULL
hodnot
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 UpdateCommand
DeleteCommand
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.
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.
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
.
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.
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.