SqlDataSource ile İyimser Eşzamanlılık Uygulama (C#)

tarafından Scott Mitchell

PDF’yi İndir

Bu öğreticide iyimser eşzamanlılık denetiminin temellerini gözden geçirecek ve ardından SqlDataSource denetimini kullanarak bunu nasıl uygulayacağımızı keşfedeceğiz.

Giriş

Önceki öğreticide, SqlDataSource denetimine ekleme, güncelleştirme ve silme özelliklerinin nasıl ekleneceğini inceledik. Kısacası, bu özellikleri sağlamak için, denetimin InsertCommand, veya özelliklerindeki ilgili INSERT, UpdateCommandUPDATEveya DELETEDeleteCommand SQL deyimini, , ve DeleteParameters koleksiyonlarındaki InsertParametersUpdateParametersuygun parametrelerle birlikte belirtmemiz gerekiyordu. Bu özellikler ve koleksiyonlar el ile belirtilebilir, ancak Veri Kaynağını Yapılandır sihirbazının Gelişmiş düğmesi, deyimini temel alarak SELECT bu deyimleri otomatik olarak oluşturacak bir , UPDATEve DELETE deyimleri oluştur INSERTonay kutusu sunar.

Gelişmiş SQL Oluşturma Seçenekleri iletişim kutusu, , UPDATEve DELETE deyimleri oluştur INSERTonay kutusunun yanı sıra İyimser eşzamanlılık kullan seçeneğini de içerir (bkz. Şekil 1). İşaretlendiğinde, WHERE otomatik oluşturulan UPDATE ve DELETE deyimlerindeki yan tümceler, yalnızca kullanıcı verileri kılavuza son yükledikten sonra temel alınan veritabanı verileri değiştirilmediyse güncelleştirmeyi veya silmeyi gerçekleştirecek şekilde değiştirilir.

Gelişmiş SQL Oluşturma Seçenekleri İletişim Kutusundan İyimser Eşzamanlılık Desteği Ekleyebilirsiniz

Şekil 1: Gelişmiş SQL Oluşturma Seçenekleri İletişim Kutusundan İyimser Eşzamanlılık Desteği Ekleyebilirsiniz

İyimser Eşzamanlılık Uygulama öğreticisine geri dönüp iyimser eşzamanlılık denetiminin temellerini ve bunu ObjectDataSource'a nasıl ekleyebileceğimizi inceledik. Bu öğreticide iyimser eşzamanlılık denetiminin temellerine rötuş yapacak ve ardından SqlDataSource'u kullanarak bunu nasıl uygulayacağımızı keşfedeceğiz.

İyimser Eşzamanlılığın Özeti

Aynı anda birden çok kullanıcının aynı verileri düzenlemesine veya silmesine izin veren web uygulamaları için, bir kullanıcının yanlışlıkla başka bir değişikliğin üzerine yazma olasılığı vardır. İyimser Eşzamanlılık Uygulama öğreticisinde aşağıdaki örneği sağladım:

Jisun ve Sam adlı iki kullanıcının, ziyaretçilerin GridView denetimi aracılığıyla ürünleri güncelleştirmesine ve silmesine izin veren bir uygulamadaki sayfayı ziyaret ettiğini düşünün. Her ikisi de Chai için düzenle düğmesine aynı anda tıklayın. Jisun, ürün adını Chai Tea olarak değiştirir ve Güncelleştir düğmesine tıklar. Net sonuç, veritabanına gönderilen ve ürünün güncelleştirilebilir alanlarının tümünü ayarlayan bir deyimdir (Jisun yalnızca bir UPDATE alanı güncelleştirmiş olsa bile). ProductName Bu noktada veritabanı Chai Tea, Beverages kategorisi, tedarikçi Egzotik Sıvılar vb. değerlerine sahiptir. Ancak, Sam ekranındaki GridView yine de düzenlenebilir GridView satırında ürün adını Chai olarak gösterir. Jisun'un değişiklikleri işlendikten birkaç saniye sonra Sam kategoriyi Condiments olarak güncelleştirir ve Güncelleştir'e tıklar. Bu, veritabanına gönderilen ve ürün adını Chai olarak, CategoryID karşılık gelen Condiments kategori kimliğine vb. ayarlayan bir UPDATE deyimle sonuçlanabilir. Jisun'un ürün adında yapılan değişikliklerin üzerine yazıldı.

Şekil 2'de bu etkileşim gösterilmektedir.

İki Kullanıcı Aynı Anda Bir Kaydı Güncelleştirdiğinde, Bir Kullanıcının DiğerInin Üzerine YazmaSına Yönelik Değişiklik Olasılığı Vardır

Şekil 2: İki Kullanıcı Bir Kaydı Aynı Anda Güncelleştirdiğinde, Bir Kullanıcının DiğerInin Üzerine Yazacak Şekilde Değişiklik Olasılığı Vardır (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Bu senaryonun ortaya çıkmasını önlemek için bir eşzamanlılık denetimi biçimi uygulanmalıdır. İyimser eşzamanlılık Bu öğreticinin odak noktası, her zaman eşzamanlılık çakışmaları olsa da, bu tür çakışmaların çoğu zaman ortaya çıkmayacağı varsayımı üzerinde çalışır. Bu nedenle, bir çakışma oluşursa iyimser eşzamanlılık denetimi, başka bir kullanıcı aynı verileri değiştirdiği için değişikliklerinin kaydedilemediğini kullanıcıya bildirir.

Not

Birçok eşzamanlılık çakışması olacağı varsayılan uygulamalar için veya bu tür çakışmalara tolerans gösterilmezse, bunun yerine kötümser eşzamanlılık denetimi kullanılabilir. Kötümser eşzamanlılık denetimi hakkında daha kapsamlı bir tartışma için İyimser Eşzamanlılık Uygulama öğreticisine bakın.

İyimser eşzamanlılık denetimi, güncelleştirilen veya silinen kaydın, güncelleştirme veya silme işlemi başladığındaki değerlerle aynı değerlere sahip olduğundan emin olarak çalışır. Örneğin, düzenlenebilir bir GridView'da Düzenle düğmesine tıklandığında, kaydın değerleri veritabanından okunur ve TextBoxes ve diğer Web denetimlerinde görüntülenir. Bu özgün değerler GridView tarafından kaydedilir. Daha sonra, kullanıcı değişikliklerini yaptıktan ve Güncelleştir düğmesine tıkladıktan sonra, UPDATE kullanılan deyim özgün değerleri ve yeni değerleri dikkate almalıdır ve yalnızca kullanıcının düzenlemeye başladığı özgün değerler veritabanındaki değerlerle aynıysa temel alınan veritabanı kaydını güncelleştirmelidir. Şekil 3'de bu olay dizisi gösterilmektedir.

Güncelleştirme veya Silme işleminin Başarılı Olması için Özgün Değerlerin Geçerli Veritabanı Değerlerine Eşit Olması Gerekir

Şekil 3: Güncelleştirme veya Silme işleminin Başarılı Olması için Özgün Değerlerin Geçerli Veritabanı Değerlerine Eşit Olması Gerekir (Tam boyutlu görüntüyü görüntülemek için tıklayın)

İyimser eşzamanlılığı uygulamaya yönelik çeşitli yaklaşımlar vardır (bir dizi seçeneğe kısa bir bakış için bkz . Peter A. Bromberg'inİyimser Eşzamanlılık Güncelleştirme Mantığı ). SqlDataSource tarafından kullanılan teknik (veri erişim katmanımızda kullanılan ADO.NET Türlenmiş Veri Kümeleri tarafından da) yan tümcesini WHERE tüm özgün değerlerin karşılaştırmasını içerecek şekilde genişletmektedir. Örneğin aşağıdaki UPDATE deyim, yalnızca geçerli veritabanı değerleri GridView'daki kayıt güncelleştirilirken alınan değerlere eşitse ürünün adını ve fiyatını güncelleştirir. @ProductName ve @UnitPrice parametreleri kullanıcı tarafından girilen yeni değerleri içerirken@original_ProductName, düzenle @original_UnitPrice düğmesine tıklandığında gridview'a yüklenen değerleri içerir:

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

Bu öğreticide göreceğimiz gibi, SqlDataSource ile iyimser eşzamanlılık denetimini etkinleştirmek, onay kutusunu işaretlemek kadar basittir.

1. Adım: İyimser Eşzamanlılığı Destekleyen Bir SqlDataSource Oluşturma

Başlangıç olarak klasörden OptimisticConcurrency.aspx sayfayı SqlDataSource açın. Bir SqlDataSource denetimini Araç Kutusu'ndan Tasarım Aracı sürükleyin, özelliğini olarak ProductsDataSourceWithOptimisticConcurrencyayarlarID. Ardından, denetimin akıllı etiketinden Veri Kaynağını Yapılandır bağlantısına tıklayın. Sihirbazın ilk ekranında, ile çalışmayı seçin ve İleri'ye NORTHWINDConnectionString tıklayın.

NORTHWINDConnectionString ile Çalışmayı Seçin

Şekil 4: Ile NORTHWINDConnectionString Çalışmayı Seçin (Tam boyutlu resmi görüntülemek için tıklayın)

Bu örnekte, kullanıcıların tabloyu düzenlemesine Products olanak tanıyan bir GridView ekleyeceğiz. Bu nedenle, Select Deyimini Yapılandır ekranında açılan listeden Products tabloyu seçin ve Şekil 5'te gösterildiği gibi , ProductName, UnitPriceve Discontinued sütunlarını seçinProductID.

Ürünler Tablosundan ProductID, ProductName, UnitPrice ve Sonlandırılan Sütunları Döndür

Şekil 5: Products Tablodan , , ProductNameUnitPriceve Discontinued Sütunlarını Döndür ProductID(Tam boyutlu görüntüyü görüntülemek için tıklayın)

Sütunları seçtikten sonra Gelişmiş düğmesine tıklayarak Gelişmiş SQL Oluşturma Seçenekleri iletişim kutusunu açın. , , UPDATEve deyimleri oluştur INSERTve DELETE İyimser eşzamanlılık kullan onay kutularını işaretleyin ve Tamam'a tıklayın (ekran görüntüsü için şekil 1'e bakın). İleri'ye ve ardından Son'a tıklayarak sihirbazı tamamlayın.

Veri Kaynağını Yapılandırma sihirbazını tamamladıktan sonra, elde DeleteCommand edilen ve özellikleri ile UpdateCommandDeleteParameters ve UpdateParameters koleksiyonlarını incelemek için biraz zaman ayırın. Bunu yapmanın en kolay yolu, sayfanın bildirim temelli söz dizimini görmek için sol alt köşedeki Kaynak sekmesine tıklamaktır. Burada şunun değerini UpdateCommand bulacaksınız:

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

Koleksiyonda yedi parametre ile 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>

Benzer şekilde, DeleteCommand özellik ve DeleteParameters koleksiyon aşağıdaki gibi görünmelidir:

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>

ve DeleteCommand özelliklerinin yan tümcelerini artırmaya WHERE (ve ilgili parametre koleksiyonlarına UpdateCommand ek parametreleri eklemeye) ek olarak, İyimser eşzamanlılık kullan seçeneğinin seçilmesi diğer iki özelliği ayarlar:

Veri Web denetimi SqlDataSource'u Update() veya Delete() yöntemini çağırdığında, özgün değerleri geçirir. SqlDataSource özelliği ConflictDetection olarak CompareAllValuesayarlanırsa, bu özgün değerler komutuna eklenir. özelliği, OldValuesParameterFormatString bu özgün değer parametreleri için kullanılan adlandırma desenini sağlar. Veri Kaynağını Yapılandırma sihirbazı original_{0} kullanır ve ve özelliklerinde ve DeleteParametersUpdateParameters koleksiyonlarındaki her özgün parametreyi DeleteCommandUpdateCommand buna göre adlandırarak.

Not

SqlDataSource denetiminin ekleme özelliklerini kullanmadığımız için özelliği ve InsertParameters koleksiyonunu kaldırmaktan InsertCommand çekinmeyin.

Değerleri Doğru İşlemeNULL

Ne yazık ki, iyimser eşzamanlılık kullanılırken Veri Kaynağını Yapılandırma sihirbazı tarafından otomatik olarak oluşturulan genişletilmiş UPDATE ve DELETE deyimleri, değer içeren NULL kayıtlarla çalışmaz. Nedenini görmek için SqlDataSource'umuzu UpdateCommandgöz önünde bulundurun:

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

UnitPrice Tablodaki sütunun Products değerleri olabilirNULL. Belirli bir kayıt için UnitPricebir NULL değere sahipse yan WHERE tümcesi bölümü [UnitPrice] = @original_UnitPriceher zaman False olarak değerlendirilir çünkü NULL = NULL her zaman False döndürür. Bu nedenle, ve DELETE deyim WHERE yan tümceleri güncelleştirilecek veya silinecek herhangi bir satır döndürmediğinden, UPDATE değer içeren NULL kayıtlar düzenlenemez veya silinemez.

Not

Bu hata ilk olarak Haziran 2004'te SqlDataSource Yanlış SQL Deyimleri Oluşturuyor'da Microsoft'a bildirildi ve ASP.NET sonraki sürümünde düzeltilmesi zamanlandı.

Bunu düzeltmek için, değerleri olabilecek tüm sütunların WHERE hem ve DeleteCommand özelliklerindeki UpdateCommand yan tümcelerini el ile güncelleştirmemiz gerekirNULL. Genel olarak şunun gibi değiştirin [ColumnName] = @original_ColumnName :

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

Bu değişiklik doğrudan bildirim temelli işaretleme aracılığıyla, Özellikler penceresi UpdateQuery veya DeleteQuery seçenekleri aracılığıyla ya da Veri Kaynağını Yapılandırma sihirbazındaki Özel SQL deyimi veya saklı yordam belirt seçeneğindeki UPDATE ve DELETE sekmeleri aracılığıyla yapılabilir. Bu değişiklik de ve DeleteCommand yan WHERE tümcesindeki UpdateCommand değer içerebilen NULLher sütun için yapılmalıdır.

Bunu örnek uygulamamız aşağıdaki değiştirilmiş UpdateCommand ve DeleteCommand değerleriyle sonuçlanır:

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

2. Adım: Düzenleme ve Silme Seçenekleriyle GridView Ekleme

SqlDataSource iyimser eşzamanlılığı destekleyecek şekilde yapılandırıldığında, geriye kalan tek şey bu eşzamanlılık denetimini kullanan sayfaya bir veri Web denetimi eklemektir. Bu öğretici için hem düzenleme hem de silme işlevi sağlayan bir GridView ekleyelim. Bunu başarmak için Bir GridView'u Araç Kutusundan Tasarım Aracı sürükleyin ve olarak IDProductsayarlayın. GridView'un akıllı etiketinden, bunu 1. Adımda eklenen SqlDataSource denetimine ProductsDataSourceWithOptimisticConcurrency bağlayın. Son olarak, akıllı etiketten Düzenlemeyi Etkinleştir ve Silmeyi Etkinleştir seçeneklerini işaretleyin.

GridView'ı SqlDataSource'a bağlama ve Düzenleme ve Silmeyi Etkinleştirme

Şekil 6: GridView'ı SqlDataSource'a bağlama ve Düzenleme ve Silmeyi Etkinleştirme (Tam boyutlu görüntüyü görüntülemek için tıklayın)

GridView'ı ekledikten sonra, BoundField'i kaldırarakProductID, BoundField özelliğini HeaderText Product olarak değiştirerek ProductName ve BoundField özelliğini yalnızca Price olacak şekilde HeaderText güncelleştirerek UnitPrice görünümünü yapılandırın. İdeal olarak, düzenleme arabirimini değer için RequiredFieldValidator ve değer için ProductName bir CompareValidator içerecek şekilde geliştirebiliriz (düzgün biçimlendirilmiş bir sayısal değer olduğundan emin olmak için UnitPrice ). GridView düzenleme arabirimini özelleştirmeye daha ayrıntılı bir bakış için Veri Değiştirme Arabirimini Özelleştirme öğreticisine bakın.

Not

GridView'dan SqlDataSource'a geçirilen özgün değerler görünüm durumunda depolandığından GridView görünüm durumunun etkinleştirilmesi gerekir.

GridView'da bu değişiklikleri yaptıktan sonra GridView ve SqlDataSource bildirim temelli işaretleme aşağıdakine benzer görünmelidir:

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

İyimser eşzamanlılık denetiminin çalıştığını görmek için iki tarayıcı penceresi açın ve sayfayı OptimisticConcurrency.aspx her ikisinde de yükleyin. Her iki tarayıcıda da ilk ürünün Düzenle düğmelerine tıklayın. Tek bir tarayıcıda ürün adını değiştirin ve Güncelleştir'e tıklayın. Tarayıcı geri döner ve GridView düzenleme öncesi moduna döner ve yeni düzenlenen kaydın yeni ürün adını gösterir.

İkinci tarayıcı penceresinde fiyatı değiştirin (ancak ürün adını özgün değeri olarak bırakın) ve Güncelleştir'e tıklayın. Geri göndermede kılavuz, ön düzenleme moduna döner, ancak fiyat değişikliği kaydedilmez. İkinci tarayıcı, eski fiyatla yeni ürün adının ilkiyle aynı değeri gösterir. İkinci tarayıcı penceresinde yapılan değişiklikler kayboldu. Ayrıca, bir eşzamanlılık ihlali oluştuğunu belirten bir özel durum veya ileti olmadığından, değişiklikler sessizce kayboldu.

İkinci Tarayıcı Penceresindeki Değişiklikler SessizCe Kayboldu

Şekil 7: İkinci Tarayıcı Penceresindeki Değişiklikler SessizCe Kayboldu (Tam boyutlu görüntüyü görüntülemek için tıklayın)

İkinci tarayıcı değişikliklerinin işlenmeme nedeni, deyiminin s WHERE yan tümcesinin UPDATE tüm kayıtları filtrelemesi ve dolayısıyla hiçbir satırı etkilememesiydi. Deyimine UPDATE yeniden göz atalım:

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

İkinci tarayıcı penceresi kaydı güncelleştirdiğinde, yan tümcesinde WHERE belirtilen özgün ürün adı mevcut ürün adıyla eşleşmiyor (ilk tarayıcı tarafından değiştirildiğinden). Bu nedenle, deyimi [ProductName] = @original_ProductName False döndürür ve UPDATE hiçbir kaydı etkilemez.

Not

Silme işlemi aynı şekilde çalışır. İki tarayıcı penceresi açıkken, belirli bir ürünü bir taneyle düzenleyip değişiklikleri kaydederek işe başlayın. Değişiklikleri bir tarayıcıya kaydettikten sonra, diğerinde aynı ürün için Sil düğmesine tıklayın. Özgün değerler deyimi s WHERE yan tümcesinde DELETE eşleşmediğinden silme işlemi sessizce başarısız olur.

İkinci tarayıcı penceresindeki son kullanıcının perspektifinden Güncelleştir düğmesine tıkladıktan sonra kılavuz ön düzenleme moduna döner, ancak değişiklikleri kaybolur. Ancak, değişikliklerinin uygulanmadığını belirten görsel bir geri bildirim yoktur. İdeal olarak, bir kullanıcının değişiklikleri eşzamanlılık ihlaline bağlı olarak kaybolursa, onu bilgilendirir ve belki de kılavuzu düzenleme modunda tutarız. Şimdi bunu nasıl gerçekleştireceklerine bakalım.

3. Adım: Eşzamanlılık İhlaliNin Ne Zaman Gerçekleştiğini Belirleme

Bir eşzamanlılık ihlali, yaptığı değişiklikleri reddettiği için, bir eşzamanlılık ihlali oluştuğunda kullanıcıyı uyarmak iyi olur. Kullanıcıyı uyarmak için, özelliği şu iletiyi görüntüleyen adlı ConcurrencyViolationMessageText sayfanın en üstüne bir Etiket Web denetimi ekleyelim: Başka bir kullanıcı tarafından aynı anda güncelleştirilen bir kaydı güncelleştirmeyi veya silmeyi denediniz. Lütfen diğer kullanıcının değişikliklerini gözden geçirin ve güncelleştirmenizi veya silme işleminizi yineleyin. Etiket denetimi s CssClass özelliğini Uyarı olarak ayarlayın. Bu, içinde tanımlanan Styles.css ve metinleri kırmızı, italik, kalın ve büyük yazı tipinde görüntüleyen bir CSS sınıfıdır. Son olarak, Etiket ve VisibleEnableViewState özelliklerini olarak falseayarlayın. Bu, yalnızca özelliğini trueaçıkça olarak olarak ayarladığımız geri göndermeler dışında Etiketi gizlerVisible.

Uyarıyı Görüntülemek için Sayfaya Etiket Denetimi Ekleme

Şekil 8: Uyarıyı Görüntülemek için Sayfaya Etiket Denetimi Ekleme (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Bir güncelleştirme veya silme gerçekleştirirken, GridView s RowUpdated ve RowDeleted olay işleyicileri, veri kaynağı denetimi istenen güncelleştirmeyi veya silmeyi gerçekleştirdikten sonra tetikler. Bu olay işleyicilerinden işlemden kaç satır etkilendiğini belirleyebiliriz. Hiç satır etkilenmediyse Etiket'i ConcurrencyViolationMessage görüntülemek istiyoruz.

hem hem RowDeleted de RowUpdated olayları için bir olay işleyicisi oluşturun ve aşağıdaki kodu ekleyin:

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;
}

Her iki olay işleyicisinde de özelliğini denetleriz e.AffectedRows ve 0'a eşitse Label s Visible özelliğini olarak trueayarlarızConcurrencyViolationMessage. Olay işleyicisinde RowUpdated , özelliği true olarak ayarlayarak KeepInEditMode GridView'a düzenleme modunda kalmasını da bildiririz. Bunu yaparken, diğer kullanıcının verilerinin düzenleme arabirimine yüklenmesi için verileri kılavuza yeniden bağlamamız gerekir. Bu, GridView s DataBind() yöntemi çağrılarak gerçekleştirilir.

Şekil 9'da gösterildiği gibi, bu iki olay işleyicisiyle eşzamanlılık ihlali oluştuğunda çok belirgin bir ileti görüntülenir.

Eşzamanlılık İhlaliNin Karşısında İleti Görüntüleniyor

Şekil 9: Eşzamanlılık İhlalinin Karşısında İleti Görüntüleniyor (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Özet

Birden çok eşzamanlı kullanıcının aynı verileri düzenleyebileceği bir web uygulaması oluştururken eşzamanlılık denetimi seçeneklerini göz önünde bulundurmak önemlidir. Varsayılan olarak, ASP.NET veri Web denetimleri ve veri kaynağı denetimleri herhangi bir eşzamanlılık denetimi kullanmaz. Bu öğreticide gördüğümüz gibi, SqlDataSource ile iyimser eşzamanlılık denetimi uygulamak nispeten hızlı ve kolaydır. SqlDataSource, otomatik olarak oluşturulan UPDATE ve deyimlerine genişletilmiş WHERE yan tümceleri eklemenize ilişkin çoğu işlemi işler, ancak Değerleri Doğru İşleme NULL bölümünde açıklandığı gibi değer sütunlarını işlemede NULL birkaç incelik DELETE vardır.

Bu öğretici, SqlDataSource incelememizi tamamlar. Kalan öğreticilerimiz ObjectDataSource ve katmanlı mimariyi kullanarak verilerle çalışmaya geri dönecektir.

Mutlu Programlama!

Yazar hakkında

Yedi ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışmaktadır. Son kitabı Sams Teach Yourself ASP.NET 24 Saat içinde 2.0. Adresine adresinden veya adresinden ulaşabileceğiniz http://ScottOnWriting.NETblogu aracılığıyla ulaşabilirsinizmitchell@4GuysFromRolla.com.