Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Scott Mitchell
Dalam tutorial ini kami meninjau hal-hal penting kontrol konkurensi optimis dan kemudian mengeksplorasi cara menerapkannya menggunakan kontrol SqlDataSource.
Pendahuluan
Dalam tutorial sebelumnya, kami memeriksa cara menambahkan kemampuan menyisipkan, memperbarui, dan menghapus ke kontrol SqlDataSource. Singkatnya, untuk menyediakan fitur-fitur ini, kami perlu menentukan pernyataan SQL yang sesuai dalam properti kontrol INSERT, UPDATE, atau DELETE, bersama dengan parameter yang sesuai dalam koleksi InsertCommand, UpdateCommand, dan DeleteCommand. Meskipun properti dan koleksi ini dapat ditentukan secara manual, tombol tingkat lanjut pada wizard Konfigurasi Sumber Data menawarkan kotak centang untuk membuat pernyataan INSERT, UPDATE, dan DELETE yang akan membuat pernyataan ini secara otomatis berdasarkan pernyataan SELECT.
Bersama dengan kotak centang Hasilkan INSERT, UPDATE, dan DELETE pernyataan, kotak dialog Opsi Pembuatan SQL Tingkat Lanjut menyertakan opsi Gunakan konkurensi optimis (lihat Gambar 1). Saat dicentang, klausul WHERE dalam pernyataan UPDATE dan DELETE yang dihasilkan secara otomatis dimodifikasi untuk hanya melakukan pembaruan atau penghapusan jika data pada database yang mendasar belum dimodifikasi sejak terakhir kali pengguna memuat data ke dalam grid.
Gambar 1: Anda Dapat Menambahkan Dukungan Konkurensi Optimis dari Kotak Dialog Opsi Pembuatan SQL Tingkat Lanjut
Kembali dalam tutorial Menerapkan Konkurensi Optimis kami memeriksa dasar-dasar kontrol konkurensi optimis dan cara menambahkannya ke ObjectDataSource. Dalam tutorial ini kita akan mengulas kembali dasar-dasar kontrol konkurensi optimis dan kemudian mengeksplorasi cara mengimplementasikannya menggunakan SqlDataSource.
Rekap Konkurensi Optimis
Untuk aplikasi web yang memungkinkan beberapa pengguna secara bersamaan mengedit atau menghapus data yang sama, ada kemungkinan bahwa satu pengguna mungkin secara tidak sengaja menimpa perubahan yang dilakukan oleh pengguna lain. Dalam tutorial Menerapkan Konkurensi Optimis Saya memberikan contoh berikut:
Bayangkan bahwa dua pengguna, Jisun dan Sam, keduanya mengunjungi halaman dalam aplikasi yang memungkinkan pengunjung untuk memperbarui dan menghapus produk melalui kontrol GridView. Keduanya mengklik tombol Edit untuk Chai sekitar waktu yang sama. Jisun mengubah nama produk menjadi Teh Chai dan mengklik tombol Perbarui. Hasil bersih adalah UPDATE pernyataan yang dikirim ke database, yang mengatur semua bidang produk yang dapat diperbarui (meskipun Jisun hanya memperbarui satu bidang, ProductName). Pada titik waktu ini, database memiliki nilai Chai Tea, kategori Minuman, pemasok Exotic Liquids, dan sebagainya untuk produk khusus ini. Namun, layar GridView di Sam s masih menampilkan nama produk di baris GridView yang dapat diedit sebagai Chai. Beberapa detik setelah perubahan Jisun diterapkan, Sam memperbarui kategori menjadi Bahan Pelengkap dan mengklik tombol Perbarui. Ini menghasilkan pernyataan UPDATE yang dikirim ke database, menetapkan nama produk menjadi Chai dan CategoryID ke ID kategori bumbu yang sesuai, dan sebagainya. Perubahan Jisun pada nama produk telah digantikan.
Gambar 2 menggambarkan interaksi ini.
Gambar 2: Ketika dua pengguna secara bersamaan memperbarui catatan, ada potensi perubahan satu pengguna menggantikan perubahan pengguna lainnya. (Klik untuk melihat gambar ukuran penuh)
Untuk mencegah skenario ini terungkap, bentuk kontrol konkurensi harus diimplementasikan. Konkurensi optimis fokus tutorial ini berdasarkan asumsi bahwa meskipun mungkin ada konflik konkurensi sesekali, sebagian besar waktu konflik tersebut tidak akan muncul. Oleh karena itu, jika konflik muncul, kontrol konkurensi optimis hanya memberi tahu pengguna bahwa perubahan mereka tidak dapat disimpan karena pengguna lain telah memodifikasi data yang sama.
Nota
Untuk aplikasi di mana diasumsikan bahwa akan ada banyak konflik konkurensi atau jika konflik tersebut tidak dapat ditoleransi, kontrol konkurensi pesimis dapat digunakan sebagai gantinya. Lihat kembali tutorial Menerapkan Konkurensi Optimis untuk diskusi yang lebih menyeluruh tentang kontrol konkurensi pesimis.
Kontrol konkurensi optimis bekerja dengan memastikan bahwa rekaman yang diperbarui atau dihapus memiliki nilai yang sama seperti saat proses pembaruan atau penghapusan dimulai. Misalnya, saat mengklik tombol Edit di GridView yang dapat diedit, nilai rekaman s dibaca dari database dan ditampilkan di Kotak Teks dan kontrol Web lainnya. Nilai asli ini disimpan oleh GridView. Kemudian, setelah pengguna membuat perubahannya dan mengklik tombol Perbarui, UPDATE pernyataan yang digunakan harus memperhitungkan nilai asli ditambah nilai baru dan hanya memperbarui catatan database yang mendasar jika nilai asli yang mulai diedit pengguna identik dengan nilai yang masih ada di database. Gambar 3 menggambarkan urutan peristiwa ini.
Gambar 3: Agar Pembaruan atau Penghapusan Berhasil, Nilai Asli Harus Sama dengan Nilai Database Saat Ini (Klik untuk melihat gambar ukuran penuh)
Ada berbagai pendekatan untuk menerapkan konkurensi optimis (lihat Logika Pembaruan Konkurensi OptimisPeter A. Bromberg untuk melihat beberapa opsi). Teknik yang digunakan oleh SqlDataSource (serta oleh ADO.NET Typed DataSets yang digunakan dalam Lapisan Akses Data milik kami) menambah WHERE klausul untuk menyertakan perbandingan terhadap semua nilai asli. Pernyataan berikut UPDATE , misalnya, memperbarui nama dan harga produk hanya jika nilai database saat ini sama dengan nilai yang awalnya diambil saat memperbarui rekaman di GridView. Parameter @ProductName dan @UnitPrice berisi nilai baru yang dimasukkan oleh pengguna, sedangkan @original_ProductName dan @original_UnitPrice berisi nilai yang awalnya dimuat ke dalam GridView saat tombol Edit diklik:
UPDATE Products SET
ProductName = @ProductName,
UnitPrice = @UnitPrice
WHERE
ProductID = @original_ProductID AND
ProductName = @original_ProductName AND
UnitPrice = @original_UnitPrice
Seperti yang akan kita lihat dalam tutorial ini, mengaktifkan kontrol konkurensi optimis dengan SqlDataSource semederhana mencentang kotak centang.
Langkah 1: Membuat SqlDataSource yang Mendukung Konkurensi Optimis
Mulailah dengan membuka halaman OptimisticConcurrency.aspx dari folder SqlDataSource. Seret kontrol SqlDataSource dari Kotak Alat ke Perancang, atur propertinya ID ke ProductsDataSourceWithOptimisticConcurrency. Selanjutnya, klik tautan Konfigurasi Sumber Data dari tag pintar kontrol. Dari layar pertama dalam wizard, pilih untuk menggunakan NORTHWINDConnectionString dan klik berikutnya.
Gambar 4: Pilih untuk Bekerja dengan NORTHWINDConnectionString (Klik untuk melihat gambar ukuran penuh)
Untuk contoh ini, kita akan menambahkan GridView yang memungkinkan pengguna mengedit Products tabel. Oleh karena itu, dari layar Konfigurasikan Pernyataan Pilih, pilih tabel Products dari daftar drop-down dan pilih kolom ProductID, ProductName, UnitPrice, dan Discontinued, seperti yang ditunjukkan pada Gambar 5.
Gambar 5: Dari Products Tabel, tampilkan Kolom ProductID, ProductName, UnitPrice, dan Discontinued (Klik untuk melihat gambar ukuran penuh)
Setelah memilih kolom, klik tombol Tingkat Lanjut untuk memunculkan kotak dialog Opsi Pembuatan SQL Tingkat Lanjut. Periksa kotak centang Buat INSERT, UPDATE, dan DELETE pernyataan dan Gunakan konkurensi optimis dan klik OK (lihat kembali ke Gambar 1 untuk cuplikan layar). Selesaikan penyihir dengan mengklik Berikutnya, lalu klik Selesai.
Setelah menyelesaikan wizard Konfigurasi Sumber Data, luangkan waktu sejenak untuk memeriksa properti DeleteCommand dan UpdateCommand serta koleksi DeleteParameters dan UpdateParameters yang dihasilkan. Cara termudah untuk melakukan ini adalah dengan mengklik tab Sumber di sudut kiri bawah untuk melihat sintaks deklaratif halaman. Anda dapat menemukan nilai 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
Dengan tujuh parameter dalam UpdateParameters koleksi:
<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>
Demikian pula, properti DeleteCommand dan koleksi DeleteParameters harus terlihat seperti berikut ini:
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>
Selain meningkatkan klausa WHERE dari properti UpdateCommand dan DeleteCommand (serta menambahkan parameter baru ke dalam koleksi parameter masing-masing), memilih opsi Gunakan konkurensi optimis akan menyesuaikan dua properti lainnya:
-
ConflictDetectionMengubah properti dariOverwriteChanges(default) menjadiCompareAllValues -
OldValuesParameterFormatStringMengubah properti dari {0} (default) menjadi original_{0} .
Ketika kontrol Web data memanggil SqlDataSource s Update() atau Delete() metode, kontrol web tersebut meneruskan nilai asli. Jika properti SqlDataSource s ConflictDetection diatur ke CompareAllValues, nilai asli ini ditambahkan ke perintah . Properti OldValuesParameterFormatString menyediakan pola penamaan yang digunakan untuk parameter nilai asli ini. Wizard Konfigurasi Sumber Data menggunakan original_{0} dan menamai setiap parameter asli dalam properti UpdateCommand dan DeleteCommand serta koleksi UpdateParameters dan DeleteParameters yang sesuai.
Nota
Karena kami tidak menggunakan kemampuan penyisipan kontrol SqlDataSource, jangan ragu untuk menghapus properti InsertCommand dan koleksinya InsertParameters.
MenanganiNULLNilai dengan Benar
Sayangnya, pernyataan UPDATE dan DELETE yang ditingkatkan secara otomatis oleh wizard Konfigurasi Sumber Data saat menggunakan konkurensi optimis tidak berfungsi dengan nilai-nilai yang berisi NULL. Untuk melihat alasannya, pertimbangkan SqlDataSource kami 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
Kolom UnitPrice dalam Products tabel dapat memiliki NULL nilai. Jika rekaman tertentu memiliki NULL nilai untuk UnitPrice, bagian klausul WHERE[UnitPrice] = @original_UnitPrice akan selalu dievaluasi ke False karena NULL = NULL selalu mengembalikan False. Oleh karena itu, rekaman dengan nilai NULL tidak dapat diedit atau dihapus, karena pernyataan UPDATE dan klausa DELETEWHERE tidak akan mengembalikan baris apa pun untuk diperbarui atau dihapus.
Nota
Bug ini pertama kali dilaporkan ke Microsoft pada bulan Juni 2004 di SqlDataSource Menghasilkan Pernyataan SQL yang Salah dan dilaporkan dijadwalkan untuk diperbaiki dalam versi ASP.NET berikutnya.
Untuk memperbaikinya, kita harus memperbarui WHERE klausa secara manual di dalam properti UpdateCommand dan DeleteCommand untuk semua kolom yang dapat memiliki NULL nilai. Secara umum, ubah [ColumnName] = @original_ColumnName menjadi:
(
([ColumnName] IS NULL AND @original_ColumnName IS NULL)
OR
([ColumnName] = @original_ColumnName)
)
Modifikasi ini dapat dilakukan langsung melalui markup deklaratif, melalui opsi UpdateQuery atau DeleteQuery dari jendela Properti, atau melalui tab PERBARUI dan HAPUS di opsi Tentukan pernyataan SQL kustom atau prosedur tersimpan di wizard Konfigurasi Sumber Data. Sekali lagi, modifikasi ini harus dilakukan untuk setiap kolom dalam klausa UpdateCommandDeleteCommandWHERE yang dapat berisi nilai NULL.
Menerapkan ini ke contoh kami menghasilkan nilai UpdateCommand dan DeleteCommand yang telah dimodifikasi berikut:
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
Langkah 2: Menambahkan GridView dengan Opsi Edit dan Hapus
Dengan SqlDataSource yang dikonfigurasi untuk mendukung konkurensi optimis, yang tersisa adalah menambahkan pengontrol Web data ke halaman yang memanfaatkan kontrol konkurensi ini. Untuk tutorial ini, mari kita tambahkan GridView yang menyediakan fungsionalitas edit dan hapus. Untuk melakukan ini, seret GridView dari Toolbox ke Designer dan atur ID ke Products. Dari tag cerdas GridView, hubungkan ke kontrol ProductsDataSourceWithOptimisticConcurrency SqlDataSource yang ditambahkan di Langkah 1. Terakhir, centang opsi Aktifkan Pengeditan dan Aktifkan Penghapusan dari tag pintar.
Gambar 6: Ikat GridView ke SqlDataSource dan Aktifkan Pengeditan dan Penghapusan (Klik untuk melihat gambar ukuran penuh)
Setelah menambahkan GridView, konfigurasikan penampilannya dengan menghapus ProductID BoundField, mengubah ProductName properti BoundField ke HeaderText Produk, dan memperbarui UnitPrice BoundField sehingga propertinya HeaderText hanyaLah Harga. Idealnya, kami sebaiknya meningkatkan antarmuka pengeditan untuk menyertakan validator-RFW untuk nilai ProductName dan validator-CV untuk nilai UnitPrice (untuk memastikan bahwa itu adalah nilai numerik yang diformat dengan benar). Lihat tutorial Menyesuaikan Antarmuka Modifikasi Data untuk tampilan yang lebih mendalam dalam menyesuaikan antarmuka pengeditan GridView.
Nota
Status tampilan GridView harus diaktifkan karena nilai asli yang diteruskan dari GridView ke SqlDataSource disimpan dalam status tampilan.
Setelah membuat modifikasi ini ke GridView, markup deklaratif GridView dan SqlDataSource akan terlihat mirip dengan yang berikut ini:
<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>
Untuk melihat kontrol optimis konkurensi dalam praktik, buka dua jendela browser dan muat halaman OptimisticConcurrency.aspx di kedua jendela. Klik pada tombol Edit untuk produk pertama di kedua peramban. Di satu browser, ubah nama produk dan klik Perbarui. Browser akan melakukan postback dan GridView akan kembali ke mode pra-pengeditan, memperlihatkan nama produk baru untuk data yang baru saja diedit.
Di jendela browser kedua, ubah harga (tetapi biarkan nama produk sebagai nilai aslinya) dan klik Perbarui. Pada postback, tabel kembali ke mode pra-pengeditannya, tetapi perubahan pada harga tidak direkam. Browser kedua menunjukkan nilai yang sama dengan yang pertama nama produk baru dengan harga lama. Perubahan yang dilakukan di jendela browser kedua hilang. Selain itu, perubahan hilang agak diam-diam, karena tidak ada pengecualian atau pesan yang menunjukkan bahwa pelanggaran konkurensi baru saja terjadi.
Gambar 7: Perubahan di Jendela Browser Kedua Hilang Secara Diam-diam (Klik untuk melihat gambar ukuran penuh)
Alasan mengapa perubahan browser kedua tidak diimplementasikan adalah karena UPDATE klausul pernyataan WHERE memfilter semua rekaman sehingga tidak memengaruhi baris apa pun. Mari kita lihat kembali pernyataan UPDATE:
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
Ketika jendela browser kedua memperbarui rekaman, nama produk asli yang ditentukan dalam WHERE klausul tidak cocok dengan nama produk yang ada (karena diubah oleh browser pertama). Oleh karena itu, pernyataan [ProductName] = @original_ProductName mengembalikan False, dan UPDATE tidak memengaruhi rekaman apa pun.
Nota
Hapus bekerja dengan cara yang sama. Dengan dua jendela browser terbuka, mulailah dengan mengedit produk tertentu dengan satu, lalu simpan perubahannya. Setelah menyimpan perubahan di satu browser, klik tombol Hapus untuk produk yang sama di yang lain. Karena nilai asli tidak cocok dalam DELETE pernyataan WHERE klausa, penghapusan gagal tanpa diketahui.
Dari sudut pandang pengguna akhir di jendela browser kedua, setelah mereka mengklik tombol Perbarui, tabel kembali ke mode sebelum pengeditan, tetapi perubahan mereka hilang. Namun, tidak ada umpan balik visual bahwa perubahan mereka tidak diterapkan. Idealnya, jika perubahan pengguna hilang karena pelanggaran konkurensi, kami akan memberi tahu mereka dan, mungkin, menjaga tabel dalam mode edit. Mari kita lihat cara mencapai ini.
Langkah 3: Menentukan Kapan Pelanggaran Konkurensi Telah Terjadi
Karena pelanggaran konkurensi menolak perubahan yang dilakukan seseorang, akan lebih baik untuk memberi tahu pengguna ketika pelanggaran konkurensi telah terjadi. Untuk memperingatkan pengguna, mari kita tambahkan kontrol Web Label ke bagian atas halaman bernama ConcurrencyViolationMessage yang propertinya Text menampilkan pesan berikut: Anda telah mencoba memperbarui atau menghapus rekaman yang diperbarui secara bersamaan oleh pengguna lain. Tinjau perubahan pengguna lain lalu ulangi pembaruan atau penghapusan Anda. Atur properti kontrol CssClass label ke 'Warning', yang merupakan kelas CSS yang ditentukan dalam Styles.css yang menampilkan teks dalam font merah, miring, tebal, dan besar. Terakhir, atur Label s Visible dan EnableViewState properti ke False. Ini akan menyembunyikan Label kecuali hanya untuk postback tersebut di mana kami secara eksplisit mengatur propertinya Visible ke True.
Gambar 8: Tambahkan Kontrol Label ke Halaman untuk Menampilkan Peringatan (Klik untuk melihat gambar ukuran penuh)
Saat melakukan pembaruan atau penghapusan, GridView dan RowUpdatedRowDeleted penanganan aktivitas diaktifkan setelah kontrol sumber datanya melakukan pembaruan atau penghapusan yang diminta. Kita dapat menentukan berapa banyak baris yang terpengaruh oleh operasi dari penanganan peristiwa ini. Jika tidak ada baris yang terpengaruh, kami ingin menampilkan ConcurrencyViolationMessage Label.
Buat penangan kejadian untuk peristiwa RowUpdated dan RowDeleted dan tambahkan kode berikut:
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
Di kedua penanganan aktivitas, kami memeriksa e.AffectedRows properti dan, jika sama dengan 0, atur ConcurrencyViolationMessage properti Label s Visible ke True. Di penanganan kejadian RowUpdated, kami juga menginstruksikan GridView untuk tetap dalam mode edit dengan mengatur properti KeepInEditMode ke benar. Dalam melakukannya, kita perlu mengikat ulang data ke kisi sehingga data pengguna lain dimuat ke antarmuka pengeditan. Ini dicapai dengan memanggil metode GridView.DataBind()
Seperti yang ditunjukkan Gambar 9, dengan dua penanganan aktivitas ini, pesan yang sangat nyata ditampilkan setiap kali pelanggaran konkurensi terjadi.
Gambar 9: Pesan Ditampilkan di Wajah Pelanggaran Konkurensi (Klik untuk melihat gambar ukuran penuh)
Ringkasan
Saat membuat aplikasi web di mana beberapa pengguna bersamaan mungkin mengedit data yang sama, penting untuk mempertimbangkan opsi kontrol konkurensi. Secara default, kontrol Web data ASP.NET dan kontrol sumber data tidak menggunakan kontrol konkurensi apa pun. Seperti yang kita lihat dalam tutorial ini, menerapkan kontrol konkurensi optimis dengan SqlDataSource relatif cepat dan mudah. SqlDataSource menangani sebagian besar kerja keras untuk menambahkan klausa yang diperkaya WHERE ke dalam pernyataan UPDATE dan DELETE yang dibuat secara otomatis, tetapi ada beberapa seluk-beluk dalam menangani kolom nilai NULL, seperti yang dibahas di bagian Penanganan Nilai NULL Yang Benar.
Tutorial ini menyimpulkan pemeriksaan kami tentang SqlDataSource. Tutorial kami yang tersisa akan kembali bekerja dengan data menggunakan ObjectDataSource dan arsitektur berjenjang.
Selamat Pemrograman!
Tentang Penulis
Scott Mitchell, penulis tujuh buku ASP/ASP.NET dan pendiri 4GuysFromRolla.com, telah bekerja sama dengan teknologi Microsoft Web sejak 1998. Scott bekerja sebagai konsultan, pelatih, dan penulis independen. Buku terbarunya adalah Sams Teach Yourself ASP.NET 2.0 dalam 24 Jam. Dia dapat dijangkau di mitchell@4GuysFromRolla.com.