SqlDataSource ile İyimser Eşzamanlılık Uygulama (VB)Implementing Optimistic Concurrency with the SqlDataSource (VB)

Scott Mitchell tarafındanby Scott Mitchell

Örnek uygulamayı indirin veya PDF 'yi indirinDownload Sample App or Download PDF

Bu öğreticide, iyimser eşzamanlılık denetiminin temel bileşenleri inceliyoruz ve ardından SqlDataSource denetimini kullanarak nasıl uygulanacağını keşfedebilirsiniz.In this tutorial we review the essentials of optimistic concurrency control and then explore how to implement it using the SqlDataSource control.

GirişIntroduction

Önceki öğreticide, SqlDataSource denetimine ekleme, güncelleştirme ve silme yeteneklerini nasıl ekleyeceğiniz incelendi.In the preceding tutorial we examined how to add inserting, updating, and deleting capabilities to the SqlDataSource control. Kısacası, bu özellikleri, UpdateCommand, DeleteCommand ve InsertParameterskoleksiyonlardaki uygun parametrelerle birlikte denetim s InsertCommand, UpdateParametersveya DeleteParameters özelliklerinde karşılık gelen INSERT, UPDATEveya DELETE SQL deyimlerinin belirtilmesi gerekiyordu.In short, to provide these features we needed to specify the corresponding INSERT, UPDATE, or DELETE SQL statement in the control s InsertCommand, UpdateCommand, or DeleteCommand properties, along with the appropriate parameters in the InsertParameters, UpdateParameters, and DeleteParameters collections. Bu özellikler ve koleksiyonlar el ile belirtiken, veri kaynağı Yapılandırma Sihirbazı s Gelişmiş düğmesi, bu ifadeleri SELECT bildirimine göre otomatik olarak oluşturacak INSERT, UPDATEve DELETE deyimler onay kutusu sunar.While these properties and collections can be specified manually, the Configure Data Source wizard s Advanced button offers a Generate INSERT, UPDATE, and DELETE statements checkbox that will auto-create these statements based on the SELECT statement.

INSERToluşturma, UPDATEve DELETE deyimleriyle birlikte, gelişmiş SQL oluşturma seçenekleri iletişim kutusu, iyimser eşzamanlılık seçeneğini kullanın (bkz. Şekil 1).Along with the Generate INSERT, UPDATE, and DELETE statements checkbox, the Advanced SQL Generation Options dialog box includes a Use optimistic concurrency option (see Figure 1). İşaretlendiğinde, otomatik olarak oluşturulan UPDATE ve DELETE deyimlerdeki WHERE yan tümceleri yalnızca, kullanıcının verileri kılavuza en son yüklemesinden bu yana temel alınan veritabanı verileri değiştirilmemişse güncelleştirme veya silme işlemleri için değiştirilir.When checked, the WHERE clauses in the autogenerated UPDATE and DELETE statements are modified to only perform the update or delete if the underlying database data hasn't been modified since the user last loaded the data into the grid.

Gelişmiş SQL oluşturma seçenekleri Iletişim kutusundan Iyimser eşzamanlılık desteği ekleyebilirsiniz

Şekil 1: Gelişmiş SQL oluşturma seçenekleri Iletişim kutusundan Iyimser eşzamanlılık desteği ekleyebilirsinizFigure 1: You Can Add Optimistic Concurrency Support from the Advanced SQL Generation Options Dialog Box

Iyimser eşzamanlılık öğreticisini uygulayarak, iyimser eşzamanlılık denetiminin temellerini ve bunu ObjectDataSource 'a eklemeyi inceledik.Back in the Implementing Optimistic Concurrency tutorial we examined the fundamentals of optimistic concurrency control and how to add it to the ObjectDataSource. Bu öğreticide, iyimser eşzamanlılık denetiminin temel bileşenleri ile iletişime geçeceğiz ve ardından SqlDataSource kullanarak nasıl uygulanacağını araştırıyoruz.In this tutorial we'll retouch on the essentials of optimistic concurrency control and then explore how to implement it using the SqlDataSource.

Iyimser eşzamanlılık bir üst sınırıA Recap of Optimistic Concurrency

Birden çok, eşzamanlı 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ği geçersiz yazabilecekleri bir olasılık vardır.For web applications that allow multiple, simultaneous users to edit or delete the same data, there exists a possibility that one user may accidentally overwrite another s changes. Iyimser eşzamanlılık öğreticisini uygulamak için aşağıdaki örneği sağladım:In the Implementing Optimistic Concurrency tutorial I provided the following example:

İki kullanıcı olan Jisun ve Sam, ziyaretçilerin bir GridView denetimiyle ürünleri güncelleştirmesine ve silmesine izin veren bir uygulamada bir sayfa ziyaret ettiğini düşünün.Imagine that two users, Jisun and Sam, were both visiting a page in an application that allowed visitors to update and delete products through a GridView control. Her ikisi de aynı anda Chai için Düzenle düğmesine tıklayın.Both click the Edit button for Chai around the same time. Jisa ürün adını Chai Tea olarak değiştirir ve Güncelleştir düğmesine tıklar.Jisun changes the product name to Chai Tea and clicks the Update button. Net sonuç, Tüm ürün öğeleri güncelleştirilebilir alanları ayarlayan veritabanına gönderilen bir UPDATE deyimidir (jıse yalnızca bir alan, ProductName).The net result is an UPDATE statement that is sent to the database, which sets all of the product s updateable fields (even though Jisun only updated one field, ProductName). Bu noktada, veritabanı Chai Tea, kategori Içnoktaları, tedarikçi Exotic Litids ve bu ürüne yönelik olarak, bu ürünün bu değerlerini içerir.At this point in time, the database has the values Chai Tea, the category Beverages, the supplier Exotic Liquids, and so on for this particular product. Ancak, Sam s ekranındaki GridView, hala, düzenlenebilir GridView satırındaki ürün adını Chai olarak gösterir.However, the GridView on Sam s screen still shows the product name in the editable GridView row as Chai. Jisun değişikliklerinin işlendiği birkaç saniye sonra, Sam kategoriyi koşullu olarak güncelleştirir ve Güncelleştir ' i tıklatır.A few seconds after Jisun s changes have been committed, Sam updates the category to Condiments and clicks Update. Bu, ürün adını Chai olarak ayarlayan veritabanına gönderilen UPDATE bildirimine, karşılık gelen koşullu kategori KIMLIĞINE CategoryID ve bu şekilde devam eder.This results in an UPDATE statement sent to the database that sets the product name to Chai, the CategoryID to the corresponding Condiments category ID, and so on. Ürün adında yapılan jisun değişikliklerinin üzerine yazıldı.Jisun s changes to the product name have been overwritten.

Şekil 2 bu etkileşimi gösterir.Figure 2 illustrates this interaction.

Iki kullanıcı aynı anda bir kaydı güncelleştirirken bir kullanıcının diğer s değişikliklerinin üzerine yazılmasına neden olacak değişikliklerWhen Two Users Simultaneously Update a Record There s Potential for One User s Changes to Overwrite the Other s

Şekil 2: Iki kullanıcı aynı anda bir kaydı güncelleştirirken, bir kullanıcının diğer öğeleri üzerine yazılmasına yönelik değişiklikler (tam boyutlu görüntüyü görüntülemek için tıklatın)Figure 2: When Two Users Simultaneously Update a Record There s Potential for One User s Changes to Overwrite the Other s (Click to view full-size image)

Bu senaryonun katlamayı engellemek için bir eşzamanlılık denetimi formu uygulanmalıdır.To prevent this scenario from unfolding, a form of concurrency control must be implemented. İyimser eşzamanlılık Bu öğreticinin odağı, şu anda eşzamanlılık çakışmaları olabileceğinden varsayımını ve sonra bu tür çakışmaların büyük çoğunluğunu görmemesi durumunda işe yarar.Optimistic concurrency the focus of this tutorial works on the assumption that while there may be concurrency conflicts every now and then, the vast majority of the time such conflicts won't arise. Bu nedenle, bir çakışma ortaya çıkarsa, iyimser eşzamanlılık denetimi kullanıcıya, farklı bir kullanıcı aynı verileri değiştirdiği için yaptıkları değişikliklerin kaydedimeyeceğini bildirir.Therefore, if a conflict does arise, optimistic concurrency control simply informs the user that their changes can t be saved because another user has modified the same data.

Note

Birçok eşzamanlılık çakışması olacağını veya bu çakışmaların tolerandışı olduğunu varsaymayan uygulamalar için, bunun yerine Kötümser eşzamanlılık denetimi kullanılabilir.For applications where it is assumed that there will be many concurrency conflicts or if such conflicts are not tolerable, then pessimistic concurrency control can be used instead. Kötümser eşzamanlılık denetimi hakkında daha kapsamlı bir tartışma için Iyimser eşzamanlılık öğreticisine geri dönün.Refer back to the Implementing Optimistic Concurrency tutorial for a more thorough discussion on pessimistic concurrency control.

İyimser eşzamanlılık denetimi, güncelleştirilmesi veya silinmekte olan kaydın güncelleştirme ya da silme işlemi başladığında yaptığı gibi aynı değerlere sahip olduğundan emin olarak çalışarak işe yarar.Optimistic concurrency control works by ensuring that the record being updated or deleted has the same values as it did when the updating or deleting process started. Örneğin, düzenlenebilir bir GridView 'da Düzenle düğmesine tıkladığınızda, kayıt değerleri veritabanından okunmalıdır ve metin kutuları ve diğer Web denetimlerinde görüntülenir.For example, when clicking the Edit button in an editable GridView, the record s values are read from the database and displayed in TextBoxes and other Web controls. Bu orijinal değerler GridView tarafından kaydedilir.These original values are saved by the GridView. Daha sonra Kullanıcı, değişiklikleri yaptıktan ve Update düğmesine tıkladıktan sonra, kullanılan UPDATE deyimin özgün değerleri ve yeni değerleri dikkate almalıdır ve yalnızca kullanıcının düzenlemesini başlattığı özgün değerler veritabanında hala aynı değerlerle aynıysa temel alınan veritabanı kaydını güncelleştirin.Later, after the user makes her changes and clicks the Update button, the UPDATE statement used must take into account the original values plus the new values and only update the underlying database record if the original values that the user started editing are identical to the values still in the database. Şekil 3 ' te bu olay dizisi gösterilmektedir.Figure 3 depicts this sequence of events.

Güncelleştirme veya silme Işleminin başarılı olması için , özgün değerler geçerli veritabanı değerlerine eşit olmalıdırFor the Update or Delete to Succeed, the Original Values Must Be Equal to the Current Database Values

Şekil 3: güncelleştirme veya silme işleminin başarılı olması Için, özgün değerler geçerli veritabanı değerlerine eşit olmalıdır (tam boyutlu görüntüyü görüntülemek için tıklatın)Figure 3: For the Update or Delete to Succeed, the Original Values Must Be Equal to the Current Database Values (Click to view full-size image)

İ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'ın Iyimser eşzamanlılık güncelleştirme mantığı ).There are various approaches to implementing optimistic concurrency (see Peter A. Bromberg's Optimistic Concurrency Updating Logic for a brief look at a number of options). SqlDataSource tarafından kullanılan teknik (ve veri erişim katmanımızda kullanılan ADO.NET türü belirtilmiş veri kümelerinde), tüm özgün değerleri bir karşılaştırma dahil etmek için WHERE yan tümcesini geliştirir.The technique used by the SqlDataSource (as well as by the ADO.NET Typed DataSets used in our Data Access Layer) augments the WHERE clause to include a comparison of all of the original values. Örneğin, aşağıdaki UPDATE deyimleriyle, bir ürünün adını ve fiyatını yalnızca geçerli veritabanı değerleri GridView 'daki kayıt güncelleştirilirken başlangıçta alınan değerlere eşitse günceller.The following UPDATE statement, for example, updates the name and price of a product only if the current database values are equal to the values that were originally retrieved when updating the record in the GridView. @ProductName ve @UnitPrice parametreleri Kullanıcı tarafından girilen yeni değerleri içerir, ancak Düzenle düğmesine tıklandığında @original_ProductName ve @original_UnitPrice ilk olarak GridView 'a yüklenmiş olan değerleri içerir:The @ProductName and @UnitPrice parameters contain the new values entered by the user, whereas @original_ProductName and @original_UnitPrice contain the values that were originally loaded into the GridView when the Edit button was clicked:

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

Bu öğreticide göreceğiniz gibi, SqlDataSource ile iyimser eşzamanlılık denetimini etkinleştirmek, bir CheckBox denetimi yapmak kadar basittir.As we'll see in this tutorial, enabling optimistic concurrency control with the SqlDataSource is as simple as checking a checkbox.

1. Adım: Iyimser eşzamanlılık destekleyen bir SqlDataSource oluşturmaStep 1: Creating a SqlDataSource that Supports Optimistic Concurrency

SqlDataSource klasöründen OptimisticConcurrency.aspx sayfasını açarak başlayın.Start by opening the OptimisticConcurrency.aspx page from the SqlDataSource folder. Araç kutusundan bir SqlDataSource denetimini tasarımcı üzerine sürükleyin, ID özelliğini ProductsDataSourceWithOptimisticConcurrencyolarak ayarlar.Drag a SqlDataSource control from the Toolbox onto the Designer, settings its ID property to ProductsDataSourceWithOptimisticConcurrency. Sonra, denetim öğeleri akıllı etiketinden veri kaynağını Yapılandır bağlantısına tıklayın.Next, click on the Configure Data Source link from the control s smart tag. Sihirbazın ilk ekranından NORTHWINDConnectionString çalışmayı seçip Ileri ' ye tıklayın.From the first screen in the wizard, choose to work with the NORTHWINDConnectionString and click Next.

NORTHWINDConnectionString ile çalışmayı seçmeChoose to Work with the NORTHWINDConnectionString

Şekil 4: NORTHWINDConnectionString ile çalışmayı seçme (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 4: Choose to Work with the NORTHWINDConnectionString (Click to view full-size image)

Bu örnekte, kullanıcıların Products tablosunu düzenlemesini sağlayan bir GridView ekleyeceğiz.For this example we'll be adding a GridView that enables users to edit the Products table. Bu nedenle, select Ifadesini Yapılandır ekranında, açılan listeden Products tablosunu seçin ve Şekil 5 ' te gösterildiği gibi ProductID, ProductName, UnitPriceve Discontinued sütunlarını seçin.Therefore, from the Configure the Select Statement screen, choose the Products table from the drop-down list and select the ProductID, ProductName, UnitPrice, and Discontinued columns, as shown in Figure 5.

Products tablosundan ProductID, ProductName, UnitPrice ve Discontinued sütunlarını döndürünFrom the Products Table, Return the ProductID, ProductName, UnitPrice, and Discontinued Columns

Şekil 5: Products tablosundan ProductID, ProductName, UnitPriceve Discontinued sütunlarını (tam boyutlu görüntüyü görüntülemek Için tıklayın) döndürünFigure 5: From the Products Table, Return the ProductID, ProductName, UnitPrice, and Discontinued Columns (Click to view full-size image)

Sütunları seçtikten sonra Gelişmiş düğmesine tıklayarak Gelişmiş SQL oluşturma seçenekleri iletişim kutusunu açın.After picking the columns, click the Advanced button to bring up the Advanced SQL Generation Options dialog box. INSERT, UPDATEve DELETE deyimlerini oluşturun ve iyimser eşzamanlılık onay kutularını kullanın ve Tamam 'a tıklayın (bir ekran görüntüsü için Şekil 1 ' e geri bakın).Check the Generate INSERT, UPDATE, and DELETE statements and Use optimistic concurrency checkboxes and click OK (refer back to Figure 1 for a screenshot). Ileri ' ye ve ardından son ' a tıklayarak Sihirbazı doldurun.Complete the wizard by clicking Next, then Finish.

Veri kaynağı Yapılandırma Sihirbazı 'nı tamamladıktan sonra, elde edilen DeleteCommand ve UpdateCommand özelliklerini ve DeleteParameters ve UpdateParameters koleksiyonlarını incelemek için bir dakikanızı ayırın.After completing the Configure Data Source wizard, take a moment to examine the resulting DeleteCommand and UpdateCommand properties and the DeleteParameters and UpdateParameters collections. Bunu yapmanın en kolay yolu, sayfanın bildirim temelli sözdizimini görmek için sol alt köşedeki kaynak sekmesine tıklamanız olur.The easiest way to do this is to click on the Source tab in the lower left corner to see the page s declarative syntax. UpdateCommand bir değeri bulacaksınız:There you will find an UpdateCommand value of:

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

UpdateParameters koleksiyonunda yedi parametre ile:With seven parameters in the UpdateParameters collection:

<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 özelliği ve DeleteParameters koleksiyonu aşağıdaki gibi görünmelidir:Similarly, the DeleteCommand property and DeleteParameters collection should look like the following:

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>

UpdateCommand ve DeleteCommand özelliklerinin WHERE yan tümcelerini genişletmenin yanı sıra (ve ilgili parametre koleksiyonlarına ek parametreler eklemek), iyimser eşzamanlılık kullan seçeneğini belirlemek diğer iki özelliği ayarlar:In addition to augmenting the WHERE clauses of the UpdateCommand and DeleteCommand properties (and adding the additional parameters to the respective parameter collections), selecting the Use optimistic concurrency option adjusts two other properties:

Data Web Control, SqlDataSource s Update() veya Delete() metodunu çağırdığında, özgün değerleri geçirir.When the data Web control invokes the SqlDataSource s Update() or Delete() method, it passes in the original values. SqlDataSource s ConflictDetection özelliği CompareAllValuesolarak ayarlandıysa, bu özgün değerler komuta eklenir.If the SqlDataSource s ConflictDetection property is set to CompareAllValues, these original values are added to the command. OldValuesParameterFormatString özelliği, bu özgün değer parametreleri için kullanılan adlandırma modelini sağlar.The OldValuesParameterFormatString property provides the naming pattern used for these original value parameters. Veri kaynağını yapılandırma Sihirbazı özgün_{0} kullanır ve UpdateCommand ve DeleteCommand özellikleri ve UpdateParameters ve DeleteParameters koleksiyonlarında her bir özgün parametreyi adlandırır.The Configure Data Source wizard uses original_{0} and names each original parameter in the UpdateCommand and DeleteCommand properties and UpdateParameters and DeleteParameters collections accordingly.

Note

SqlDataSource denetim ekleme özelliklerini kullandığımızdan, InsertCommand özelliğini ve InsertParameters koleksiyonunu kaldırmayı ücretsiz olarak hissettik.Since we re not using the SqlDataSource control s inserting capabilities, feel free to remove the InsertCommand property and its InsertParameters collection.

NULLdeğerlerini doğru şekilde IşlemeCorrectly HandlingNULLValues

Ne yazık ki, iyimser eşzamanlılık kullanılırken genişletilmiş UPDATE ve DELETE deyimleri veri kaynağını yapılandırma Sihirbazı tarafından otomatik olarak oluşturulur NULL değerler içeren kayıtlarla çalışmaz.Unfortunately, the augmented UPDATE and DELETE statements autogenerated by the Configure Data Source wizard when using optimistic concurrency do not work with records that contain NULL values. Nedenini görmek için, SqlDataSource s UpdateCommandgöz önünde bulundurun:To see why, consider our SqlDataSource s 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

Products tablosundaki UnitPrice sütununda NULL değeri olabilir.The UnitPrice column in the Products table can have NULL values. Belirli bir kaydın UnitPriceiçin NULL bir değeri varsa, NULL = NULL her zaman false döndürdüğünden [UnitPrice] = @original_UnitPrice WHERE yan tümce bölümü her zaman false olarak değerlendirilir.If a particular record has a NULL value for UnitPrice, the WHERE clause portion [UnitPrice] = @original_UnitPrice will always evaluate to False because NULL = NULL always returns False. Bu nedenle, UPDATE ve DELETE deyimleri WHERE yan tümceleri güncelleştirmek veya silmek için herhangi bir satır döndürülmeyeceği için NULL değerleri içeren kayıtlar düzenlenemez veya silinemez.Therefore, records that contain NULL values cannot be edited or deleted, as the UPDATE and DELETE statements WHERE clauses won't return any rows to update or delete.

Note

Bu hata ilk olarak Microsoft 'a, SqlDataSource 'da 2004 Haziran ayında yanlış SQL deyimleri oluşturuyor ve ASP.net 'in bir sonraki sürümünde düzeltilmesi planlanacaktır.This bug was first reported to Microsoft in June of 2004 in SqlDataSource Generates Incorrect SQL Statements and is reportedly scheduled to be fixed in the next version of ASP.NET.

Bunu yapmak için, NULL değerlerine sahip olan Tüm sütunlar için hem UpdateCommand hem de DeleteCommand özelliklerde WHERE yan tümceleri el ile güncelleştirmemiz gerekir.To fix this, we have to manually update the WHERE clauses in both the UpdateCommand and DeleteCommand properties for all columns that can have NULL values. Genel olarak [ColumnName] = @original_ColumnName şu şekilde değiştirin:In general, change [ColumnName] = @original_ColumnName to:

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

Bu değişiklik bildirime dayalı biçimlendirme aracılığıyla doğrudan, Özellikler penceresi UpdateQuery veya DeleteQuery seçenekleri aracılığıyla ya da veri yapılandırma içindeki özel bir SQL deyimi veya saklı yordam belirleme seçeneğinde GÜNCELLEŞTIRME ve SILME sekmeleri aracılığıyla yapılabilir Kaynak Sihirbazı.This modification can be made directly through the declarative markup, via the UpdateQuery or DeleteQuery options from the Properties window, or through the UPDATE and DELETE tabs in the Specify a custom SQL statement or stored procedure option in the Configure Data Source wizard. Bu değişiklik, UpdateCommand ve DeleteCommand s WHERE yan tümcesindeki NULL değerleri içerebilen her sütun için yapılmalıdır.Again, this modification must be made for every column in the UpdateCommand and DeleteCommand s WHERE clause that can contain NULL values.

Bunu örneğimize uygulamak aşağıdaki değiştirilen UpdateCommand ve DeleteCommand değerlerine neden olur:Applying this to our example results in the following modified UpdateCommand and DeleteCommand values:

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 eklemeStep 2: Adding a GridView with Edit and Delete Options

İyimser eşzamanlılığı destekleyecek şekilde yapılandırılmış SqlDataSource ile, bu eşzamanlılık denetimini kullanan sayfaya bir veri Web denetimi eklemektir.With the SqlDataSource configured to support optimistic concurrency, all that remains is to add a data Web control to the page that utilizes this concurrency control. Bu öğreticide, s için hem düzenleme hem de silme işlevselliği sağlayan bir GridView ekleyelim.For this tutorial, let s add a GridView that provides both edit and delete functionality. Bunu gerçekleştirmek için araç kutusundan Tasarımcı üzerine bir GridView sürükleyin ve ID Productsolarak ayarlayın.To accomplish this, drag a GridView from the Toolbox onto the Designer and set its ID to Products. GridView s akıllı etiketinden, 1. adımda eklenen ProductsDataSourceWithOptimisticConcurrency SqlDataSource denetimine bağlayın.From the GridView s smart tag, bind it to the ProductsDataSourceWithOptimisticConcurrency SqlDataSource control added in Step 1. Son olarak, düzenlemenizi etkinleştir ve akıllı etiketteki silme seçeneklerini etkinleştir seçeneğini işaretleyin.Finally, check the Enable Editing and Enable Deleting options from the smart tag.

GridView 'ı SqlDataSource 'a bağlamak ve Düzenle ve silmeyi etkinleştirmek Bind the GridView to the SqlDataSource and Enable Editing and Deleting

Şekil 6: GridView 'ı SqlDataSource 'a bağlayın ve düzenlemenizi ve silmeyi etkinleştirin (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 6: Bind the GridView to the SqlDataSource and Enable Editing and Deleting (Click to view full-size image)

GridView eklendikten sonra, ProductID BoundField ' ı kaldırarak ve ProductName BoundField s HeaderText özelliğini ürün olarak değiştirerek ve HeaderText özelliğinin yalnızca fiyatı olacak şekilde UnitPrice BoundField güncelleyerek görünümünü yapılandırın.After adding the GridView, configure its appearance by removing the ProductID BoundField, changing the ProductName BoundField s HeaderText property to Product, and updating the UnitPrice BoundField so that its HeaderText property is simply Price. İdeal olarak, ProductName değeri için bir RequiredFieldValidator ve UnitPrice değeri için bir CompareValidator (düzgün şekilde biçimlendirilen bir sayısal değer olduğundan emin olmak için) için bir RequiredFieldValidator eklemek üzere, düzen arabirimini geliştirdik.Ideally, we d enhance the editing interface to include a RequiredFieldValidator for the ProductName value and a CompareValidator for the UnitPrice value (to ensure it s a properly formatted numeric value). Daha ayrıntılı bir bakış için bkz. veri değişikliği arabirimi öğreticisini özelleştirme, GridView s Düzenle arabirimini özelleştirmeye bakın.Refer to the Customizing the Data Modification Interface tutorial for a more in-depth look at customizing the GridView s editing interface.

Note

GridView 'dan SqlDataSource 'a geçirilen özgün değerler görüntüleme durumunda depolandığından, GridView s görünüm durumu etkinleştirilmelidir.The GridView s view state must be enabled since the original values passed from the GridView to the SqlDataSource are stored in view state.

GridView 'da bu değişiklikleri yaptıktan sonra GridView ve SqlDataSource bildirim temelli biçimlendirme aşağıdakine benzer olmalıdır:After making these modifications to the GridView, the GridView and SqlDataSource declarative markup should look similar to the following:

<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 denetimini çalışırken görmek için iki tarayıcı penceresi açın ve OptimisticConcurrency.aspx sayfasını her ikisine de yükleyin.To see the optimistic concurrency control in action, open two browser windows and load the OptimisticConcurrency.aspx page in both. Her iki tarayıcıda da ilk ürünün düzenleme düğmelerine tıklayın.Click on the Edit buttons for the first product in both browsers. Tek bir tarayıcıda ürün adını değiştirin ve Güncelleştir ' e tıklayın.In one browser, change the product name and click Update. Tarayıcı geri göndermeye ve GridView, yeni düzenlenen kayıt için yeni ürün adını gösterecek şekilde ön düzenleme moduna geri döner.The browser will postback and the GridView will return to its pre-editing mode, showing the new product name for the record just edited.

İ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.In the second browser window, change the price (but leave the product name as its original value) and click Update. Geri göndermede, kılavuz, ön Düzenle moduna geri döner, ancak fiyata yapılan değişiklik kaydedilmez.On postback, the grid returns to its pre-editing mode, but the change to the price is not recorded. İkinci tarayıcı, eski fiyata sahip olan ilk yeni ürün adıyla aynı değeri gösterir.The second browser shows the same value as the first one the new product name with the old price. İkinci tarayıcı penceresinde yapılan değişiklikler kayboldu.The changes made in the second browser window were lost. Üstelik, bir eşzamanlılık ihlalinin gerçekleşmediğini belirten bir özel durum veya ileti olmadığından, değişiklikler sessizce kaybedilir.Moreover, the changes were lost rather quietly, as there was no exception or message indicating that a concurrency violation just occurred.

Ikinci tarayıcı penceresindeki değişiklikler sessizce kayboldu The Changes in the Second Browser Window Were Silently Lost

Şekil 7: Ikinci tarayıcı penceresindeki değişiklikler sessizce kayboldu (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 7: The Changes in the Second Browser Window Were Silently Lost (Click to view full-size image)

İkinci tarayıcı değişikliklerinin neden yürütülmedi, UPDATE deyimi WHERE yan tümcesi tüm kayıtları filtreledi ve bu nedenle herhangi bir satırı etkilemediği için oldu.The reason why the second browser s changes were not committed was because the UPDATE statement s WHERE clause filtered out all records and therefore did not affect any rows. UPDATE deyiminize tekrar göz atalım:Let s look at the UPDATE statement again:

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, WHERE yan tümcesinde belirtilen özgün ürün adı, var olan ürün adı ile eşleşmiyor (ilk tarayıcı tarafından değiştirildiğinden).When the second browser window updates the record, the original product name specified in the WHERE clause doesn t match up with the existing product name (since it was changed by the first browser). Bu nedenle, deyimin [ProductName] = @original_ProductName false değerini döndürür ve UPDATE hiçbir kaydı etkilemez.Therefore, the statement [ProductName] = @original_ProductName returns False, and the UPDATE does not affect any records.

Note

Aynı şekilde çalışma öğesini silin.Delete works in the same manner. İki tarayıcı penceresi açıkken, belirli bir ürünü tek bir düzenleyerek ve sonra değişiklikleri kaydederek başlayın.With two browser windows open, start by editing a given product with one, and then saving its changes. Değişiklikleri tek bir tarayıcıda kaydettikten sonra, diğer üründe aynı ürünün Sil düğmesine tıklayın.After saving the changes in the one browser, click the Delete button for the same product in the other. Özgün değerler DELETE deyimi s WHERE yan tümcesinde eşleşmediğinden, silme işlemi sessizce başarısız olur.Since the original values don t match up in the DELETE statement s WHERE clause, the delete silently fails.

İkinci tarayıcı penceresinde Son Kullanıcı perspektifinden, güncelleştirme düğmesine tıkladıktan sonra kılavuz, ön Düzenle moduna geri döner, ancak değişiklikleri kaybedilir.From the end user s perspective in the second browser window, after clicking the Update button the grid returns to the pre-editing mode, but their changes were lost. Ancak, değişikliklerinin hiçbir görsel geri bildirimi yok.However, there s no visual feedback that their changes didn't stick. İdeal olarak, bir Kullanıcı değişikliklerinin eşzamanlılık ihlaline karşı kaybolması durumunda onlara bildirimde bulunur ve belki de Kılavuzu düzenleme modunda tutabilirsiniz.Ideally, if a user s changes are lost to a concurrency violation, we d notify them and, perhaps, keep the grid in edit mode. Bunun nasıl yapılacağını göz atalım.Let s look at how to accomplish this.

3. Adım: bir eşzamanlılık Ihlalinin ne zaman gerçekleştiğini belirlemeStep 3: Determining When a Concurrency Violation Has Occurred

Bir eşzamanlılık ihlali yaptığı değişiklikleri reddettiğinde, bir eşzamanlılık ihlali oluştuğunda kullanıcıyı uyarmak iyi olacaktır.Since a concurrency violation rejects the changes one has made, it would be nice to alert the user when a concurrency violation has occurred. Kullanıcıyı uyarmak için, ConcurrencyViolationMessage adlı sayfanın en üstüne, Text özelliği şu iletiyi görüntüleyen bir etiket Web denetimi ekleyelim: başka bir kullanıcı tarafından aynı anda güncelleştirilmiş bir kaydı güncelleştirmeye veya silmeye çalıştınız.To alert the user, let s add a Label Web control to the top of the page named ConcurrencyViolationMessage whose Text property displays the following message: You have attempted to update or delete a record that was simultaneously updated by another user. Lütfen diğer kullanıcının değişikliklerini gözden geçirin ve sonra güncelleştirmenizi veya silmeyi yeniden yapın.Please review the other user's changes and then redo your update or delete. Etiketi Control s CssClass özelliğini, bir kırmızı, italik, kalın ve büyük yazı tipinde metin görüntüleyen Styles.css tanımlanmış bir CSS sınıfı olan uyarı olarak ayarlayın.Set the Label control s CssClass property to Warning, which is a CSS class defined in Styles.css that displays text in a red, italic, bold, and large font. Son olarak, etiket s Visible ve EnableViewState özelliklerini Falseolarak ayarlayın.Finally, set the Label s Visible and EnableViewState properties to False. Bu, yalnızca Visible özelliğini açıkça Trueolarak ayarlamış olduğumuz geri göndermeler haricinde etiketi gizler.This will hide the Label except for only those postbacks where we explicitly set its Visible property to True.

Uyarıyı göstermek için sayfaya bir etiket denetimi eklemek Add a Label Control to the Page to Display the Warning

Şekil 8: uyarıyı görüntülemek için sayfaya bir etiket denetimi ekleyin (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 8: Add a Label Control to the Page to Display the Warning (Click to view full-size image)

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 harekete geçmektedir.When performing an update or delete, the GridView s RowUpdated and RowDeleted event handlers fire after its data source control has performed the requested update or delete. Bu olay işleyicilerinden işlemden kaç satır etkilendiğini belirleyebiliriz.We can determine how many rows were affected by the operation from these event handlers. Sıfır satır etkileniyorsa, ConcurrencyViolationMessage etiketini göstermek istiyoruz.If zero rows were affected, we want to display the ConcurrencyViolationMessage Label.

Hem RowUpdated hem de RowDeleted olayları için bir olay işleyicisi oluşturun ve aşağıdaki kodu ekleyin:Create an event handler for both the RowUpdated and RowDeleted events and add the following code:

Protected Sub Products_RowUpdated(sender As Object, e As GridViewUpdatedEventArgs) _
    Handles Products.RowUpdated
    If e.AffectedRows = 0 Then
        ConcurrencyViolationMessage.Visible = True
        e.KeepInEditMode = True
        ' Rebind the data to the GridView to show the latest changes
        Products.DataBind()
    End If
End Sub
Protected Sub Products_RowDeleted(sender As Object, e As GridViewDeletedEventArgs) _
    Handles Products.RowDeleted
    If e.AffectedRows = 0 Then
        ConcurrencyViolationMessage.Visible = True
    End If
End Sub

Her iki olay işleyicilerinde de e.AffectedRows özelliğini denetliyoruz ve 0 ' a eşitse, ConcurrencyViolationMessage Label s Visible özelliğini Trueolarak ayarlayın.In both event handlers we check the e.AffectedRows property and, if it equals 0, set the ConcurrencyViolationMessage Label s Visible property to True. RowUpdated olay işleyicisinde, GridView 'un, KeepInEditMode özelliğini true olarak ayarlayarak düzenleme modunda kalmasını de sağlarız.In the RowUpdated event handler, we also instruct the GridView to stay in edit mode by setting the KeepInEditMode property to true. Bunu yaparken, verileri kılavuza yeniden bağlamanız gerekir, böylece diğer Kullanıcı verileri, düzen arabirimine yüklenir.In doing so, we need to rebind the data to the grid so that the other user s data is loaded into the editing interface. Bu, GridView s DataBind() yöntemi çağırarak gerçekleştirilir.This is accomplished by calling the GridView s DataBind() method.

Şekil 9 ' da gösterildiği gibi, bu iki olay işleyicileriyle bir eşzamanlılık ihlali meydana geldiğinde çok dikkat çekici bir ileti görüntülenir.As Figure 9 shows, with these two event handlers, a very noticeable message is displayed whenever a concurrency violation occurs.

bir Ileti eşzamanlılık Ihlalinin Yüzinde görüntülenirA Message is Displayed in the Face of a Concurrency Violation

Şekil 9: bir Ileti eşzamanlılık Ihlali tarafında görüntülenir (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 9: A Message is Displayed in the Face of a Concurrency Violation (Click to view full-size image)

ÖzetSummary

Birden çok eş zamanlı kullanıcının aynı verileri düzenlemekte olabileceği bir Web uygulaması oluştururken, eşzamanlılık denetim seçeneklerini göz önünde bulundurmanız önemlidir.When creating a web application where multiple, concurrent users may be editing the same data, it is important to consider concurrency control options. Varsayılan olarak, ASP.NET Data Web denetimleri ve veri kaynağı denetimleri herhangi bir eşzamanlılık denetimi kullanmaz.By default, the ASP.NET data Web controls and data source controls do not employ any concurrency control. Bu öğreticide gördüğünüz gibi, SqlDataSource ile iyimser eşzamanlılık denetimini uygulamak nispeten hızlı ve kolaydır.As we saw in this tutorial, implementing optimistic concurrency control with the SqlDataSource is relatively quick and easy. SqlDataSource, otomatik olarak düzenlenen UPDATE ve DELETE deyimlerine genişletilmiş WHERE yan tümceleri eklemek için yasalların çoğunu işler, ancak NULL değerlerini doğru şekilde Işleme bölümünde anlatıldığı gibi, NULL değer sütunlarını işlemek için birkaç alt tledide vardır.The SqlDataSource handles most of the legwork for your adding augmented WHERE clauses to the autogenerated UPDATE and DELETE statements but there are a few subtleties in handling NULL value columns, as discussed in the Correctly Handling NULL Values section.

Bu öğretici, SqlDataSource incelemesini yerine eriyor.This tutorial concludes our examination of the SqlDataSource. Kalan öğreticilerimiz, ObjectDataSource ve katmanlı mimari kullanılarak verilerle çalışmaya geri dönecektir.Our remaining tutorials will return to working with data using the ObjectDataSource and tiered architecture.

Programlamanın kutlu olsun!Happy Programming!

Yazar hakkındaAbout the Author

4GuysFromRolla.com 'in, Scott Mitchell, yedi ASP/ASP. net books ve 'in yazarı, 1998 sürümünden bu yana Microsoft Web teknolojileriyle çalışmaktadır.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott bağımsız danışman, Trainer ve yazıcı olarak çalışıyor.Scott works as an independent consultant, trainer, and writer. En son kitabı, 24 saat içinde ASP.NET 2,0 kendi kendinize eğitimister.His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. mitchell@4GuysFromRolla.comadresinden erişilebilir .He can be reached at mitchell@4GuysFromRolla.com. ya da blog aracılığıyla http://ScottOnWriting.NETbulabilirsiniz.or via his blog, which can be found at http://ScottOnWriting.NET.