Seperti yang kami sebutkan sebelumnya, kontrol terikat data menyimpan nilai yang diteruskan ke sumber data dalam kamus Kunci, Nilai (nilai baru), dan Nilai Lama yang independen. Secara default, SqlDataSource dan ObjectDataSource mengabaikan bidang OldValues dan hanya menggunakan Kunci dan Nilai. Perilaku ini terdeteksi oleh properti ConflictDetection sumber data, yang diatur ke OverwriteChanges secara default. Pola OverwriteChanges berarti "hanya cocok dengan nilai kunci utama untuk memperbarui atau menghapus catatan". Operasi ini berarti bahwa pembaruan atau penghapusan catatan tidak memperhitungkan apakah nilai dasar catatan telah berubah. Dalam keadaan normal, keadaan ideal adalah membiarkan operasi Perbarui atau Hapus berhasil hanya ketika nilai baris data sama persis dengan nilai yang dipilih semula. Dalam situasi ideal ini, jika pengguna lain memperbarui baris antara waktu Anda memilihnya dan waktu Anda memperbaruinya, operasi pembaruan Anda akan gagal. Sumber data juga mendukung operasi ini dengan mengatur properti ConflictDetection ke CompareAllValues. Dalam mode ini, sumber data akan menerapkan OldValues ke perintah atau metode, dan akan menggunakan nilai-nilai ini untuk memastikan bahwa operasi pembaruan atau penghapusan harus cocok dengan semua nilai catatan sebelum memperbarui atau menghapus catatan. Anda juga harus menyetel properti OldValuesParameterFormatString ke string format komponen .NET Framework yang valid (seperti "original_{0}") untuk menunjukkan bagaimana parameter dalam kamus OldValues dan Keys harus diganti namanya untuk membedakannya dari parameter NewValues .
Contoh kode berikut menunjukkan perintah SQL khas yang digunakan oleh kontrol SqlDataSource dalam mode OverwriteChanges dan CompareAllValues. Bidang ID diasumsikan sebagai bidang kunci utama. Perhatikan bahwa perintah terakhir membandingkan semua nilai mentah dari baris data dalam klausa WHERE, bukan hanya kunci utama. Dalam hal ini, OldValuesParameterFormatString sumber data perlu disetel ke "original_{0}".
PILIH [ID], [Nama], [Alamat] dari [Kontak]
-- TimpaPerubahan
UPDATE [Kontak] SET [Nama] = @Nama, [Alamat] = @Alamat WHERE [ID] = @ID
HAPUS DARI [Kontak] DIMANA [ID] = @ID
-- BandingkanSemuaNilai
UPDATE [Kontak] SET [Nama] = @Nama, [Alamat] = @Alamat WHERE [ID] = @ID_asli
DAN [Nama] = @Nama_asli DAN [Alamat] = @Alamat_asli
HAPUS DARI [Kontak] DIMANA [ID] = @ID_asli DAN [Nama] = @Nama_asli
DAN [Alamat] = @original_Address
Harap diperhatikan bahwa OldValues tidak diperlukan untuk operasi Sisipkan, dan Deteksi Konflik hanya berarti untuk operasi Perbarui dan Hapus.
Contoh berikut menunjukkan perilaku ketika terjadi konflik. Untuk menjalankan contoh ini, Anda harus membuka dua contoh di dua jendela browser terpisah (klik "Jalankan Sampel" dua kali). Kemudian klik tombol "Edit" pada baris yang sama dari kedua formulir untuk memasukkan baris tersebut ke mode edit. Ubah nilai di jendela pertama dan klik "Perbarui". Harap dicatat bahwa pembaruan berhasil. Di jendela kedua, masukkan nilai baru di baris dan klik "Perbarui". Operasi pembaruan ini tidak berhasil karena nilai baris data yang mendasarinya telah diubah oleh operasi pembaruan pertama. Contoh ini memeriksa properti AffectedRows dari parameter peristiwa Diperbarui atau Dihapus, yaitu 0 untuk mengonfirmasi bahwa konflik telah terjadi.
<skrip runat="server">
Sub SqlDataSource1_Updated yang Dilindungi (pengirim Sebagai Objek, dan Sebagai SqlDataSourceStatusEventArgs)
Jika e.AffectedRows = 0 Maka
Response.Write("Baris diubah, pembaruan dibatalkan<br />")
Akhiri Jika
Sub Akhir Sub
Dilindungi SqlDataSource1_Deleted (pengirim Sebagai Objek, dan Sebagai SqlDataSourceStatusEventArgs)
Jika e.AffectedRows = 0 Maka
Response.Write("Baris diubah, penghapusan dibatalkan<br />")
Akhiri Jika
Akhiri Sub
</script>
Saat Perbarui atau Hapus menggunakan UI templat, nilai lama bidang pengikatan data dua arah yang menggunakan sintaks Bind akan dipertahankan. Untuk Hapus, ini berarti Anda harus menggunakan sintaks Bind untuk nilai terikat data di ItemTemplate. Tujuannya adalah untuk mempertahankan nilai lama yang diperlukan untuk operasi penghapusan. Contoh berikut menunjukkan teknik ini.
<Kolom>
<asp:CommandField ShowDeleteButton="Benar" ShowEditButton="Benar" />
<Templat Barang>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("ContactID") %>'></asp:Label>
</Templat Barang>
<EditItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("ContactID") %>'></asp:Label>
</EditItemTemplate>
</asp:TemplateField>
<Templat Barang>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("NamaKontak") %>'></asp:Label>
</Templat Barang>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("NamaKontak") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Kolom>
</asp:GridView>
Anda dapat menangani kesalahan deteksi konflik dengan lembut dengan memberi tahu pengguna bahwa data pokok telah diubah, menampilkan nilai yang diubah kepada pengguna, dan mengizinkan pengguna memilih untuk mengirimkan atau meninggalkan operasi mereka. Contoh berikut menunjukkan salah satu cara yang mungkin untuk menangani deteksi konflik. Perhatikan bahwa parameter peristiwa RowUpdated DetailsView diteruskan kamus yang dapat digunakan untuk mendeteksi nilai yang dimasukkan pengguna. Anda juga dapat mengatur properti KeepInEditMode dari parameter peristiwa ini untuk menjaga DetailsView dalam mode edit sementara pengguna memutuskan cara menangani konflik. Contoh ini menguji pendekatan serupa dengan yang sebelumnya, membuka dua jendela secara bersamaan untuk membuat pembaruan yang saling bertentangan.
Sub DetailsView1_ItemUpdated yang Dilindungi (Pengirim ByVal Sebagai Objek, ByVal dan Sebagai System.Web.UI.WebControls.DetailsViewUpdatedEventArgs)
Jika e.AffectedRows = 0 Maka
' Letakkan DetailsView dalam mode edit dan sinkronkan dengan database e.KeepInEditMode = True
DetailView1.DataBind()
' Isi kembali DetailsView dengan nilai yang dimasukkan pengguna
Redupkan Sebagai Kotak Teks
t = DetailsView1.Rows(1).Cells(1).Controls(0)
t.Teks = e.Nilai Baru("Tanggal Pemesanan")
t = DetailsView1.Rows(2).Cells(1).Controls(0)
t.Teks = e.Nilai Baru("Negara Kapal")
ErrorPanel.Visible = Benar
Kalau tidak
ErrorPanel.Visible = Salah
Akhiri Jika
Sub Akhir
Sub Detail DilindungiView1_ModeChanging(Pengirim ByVal Sebagai Objek, ByVal dan Sebagai System.Web.UI.WebControls.DetailsViewModeEventArgs)
Jika e.CancelingEdit = Benar Dan Juga ErrorPanel.Visible = Benar Maka
ErrorPanel.Visible = Salah
Akhiri Jika
Situasinya serupa ketika
End Sub
menggunakan ObjectDataSource.Perhatikan bahwa karena properti ConflictDetection sumber data diatur ke CompareAllValues, sumber data akan mencari kelebihan UpdateContact yang menerima nilai mentah setiap bidang objek Kontak.
Anda juga dapat menggunakan properti DataObjectTypeName dan CompareAllValues secara bersamaan. Dalam hal ini, ObjectDataSource mencari kelebihan UpdateContact yang hanya menerima dua parameter (keduanya Kontak). Parameter pertama adalah objek Kontak yang menyimpan nilai baru, dan parameter kedua adalah objek Kontak yang menyimpan nilai lama.