Share via


Menghasilkan Perintah dengan CommandBuilders

Ketika properti SelectCommand ditentukan secara dinamis pada durasi, seperti melalui alat kueri yang mengambil perintah tekstual dari pengguna, Anda mungkin tidak dapat menentukan, InsertCommand, UpdateCommand, atau DeleteCommand pada waktu desain yang sesuai. Jika DataTable Anda memetakan menuju atau dihasilkan dari satu tabel database, Anda dapat memanfaatkan objek DbCommandBuilder untuk secara otomatis menghasilkan DeleteCommand, InsertCommand, dan UpdateCommand dari DbDataAdapter.

Sebagai persyaratan minimum, Anda harus mengatur properti SelectCommand agar pembuatan perintah otomatis berfungsi. Skema tabel yang diambil oleh properti SelectCommand menentukan sintaksis pernyataan INSERT, UPDATE, dan DELETE yang dihasilkan secara otomatis.

DbCommandBuilder harus menjalankan SelectCommand untuk mengembalikan metadata yang diperlukan untuk membuat perintah INSERT, UPDATE, dan DELETE SQL. Akibatnya, perjalanan ekstra ke sumber data pun diperlukan, dan ini dapat menghambat performa. Untuk mencapai performa optimal, tentukan perintah Anda secara eksplisit daripada menggunakan DbCommandBuilder.

SelectCommand juga harus mengembalikan setidaknya satu kunci primer atau kolom unik. Jika tidak ada, pengecualian InvalidOperation dihasilkan, dan perintah tidak dihasilkan.

Ketika dikaitkan dengan DataAdapter, DbCommandBuilder secara otomatis menghasilkan properti InsertCommand, UpdateCommand, dan DeleteCommand dari DataAdapter jika mereka adalah referensi null. Jika Command sudah ada untuk properti, properti Command yang ada akan digunakan.

Tampilan database yang dibuat dengan menggabungkan dua tabel atau lebih bersama-sama tidak dianggap sebagai tabel database tunggal. Dalam hal ini Anda tidak dapat menggunakan DbCommandBuilder untuk menghasilkan perintah secara otomatis; Anda harus menentukan perintah Anda secara eksplisit. Untuk informasi tentang mengatur perintah secara eksplisit untuk mengatasi pembaruan DataSetkembali ke sumber data, lihat Memperbarui Sumber Data dengan DataAdapters.

Anda mungkin ingin memetakan parameter output kembali ke baris DataSet yang diperbarui. Salah satu tugas umum adalah mengambil nilai bidang identitas yang dihasilkan secara otomatis atau stempel waktu dari sumber data. DbCommandBuilder tidak akan memetakan parameter output ke kolom dalam baris yang diperbarui secara default. Dalam hal ini, Anda harus menentukan perintah Anda secara eksplisit. Untuk contoh pemetaan bidang identitas yang dihasilkan secara otomatis kembali ke kolom baris yang disisipkan, lihat Mengambil Identitas atau Nilai NomorOtomatis.

Aturan untuk Perintah yang Dibuat Secara Otomatis

Tabel berikut ini memperlihatkan aturan tentang bagaimana perintah yang dihasilkan secara otomatis dihasilkan.

Perintah Aturan
InsertCommand Masukkan baris di sumber data untuk semua baris dalam tabel dengan RowState dari Added. Masukkan nilai untuk semua kolom yang dapat diperbarui (tetapi bukan kolom seperti identitas, ekspresi, atau tanda waktu).
UpdateCommand Perbarui baris di sumber data untuk semua baris dalam tabel dengan RowState dari Modified. Perbarui nilai semua kolom kecuali untuk kolom yang tidak dapat diperbarui, seperti identitas atau ekspresi. Perbarui semua baris di mana nilai kolom di sumber data cocok dengan nilai kolom kunci utama baris, dan di mana kolom yang tersisa di sumber data cocok dengan nilai asli baris. Untuk informasi selengkapnya, lihat "Model Konkurensi Optimis untuk Pembaruan dan Penghapusan," nanti dalam topik ini.
DeleteCommand Hapus baris di sumber data untuk semua baris dalam tabel dengan RowState dari Deleted. Hapus semua baris di mana nilai kolom di sumber data cocok dengan nilai kolom kunci utama baris, dan di mana kolom yang tersisa di sumber data cocok dengan nilai asli baris. Untuk informasi selengkapnya, lihat "Model Konkurensi Optimis untuk Pembaruan dan Penghapusan," nanti dalam topik ini.

Model Konkurensi Optimis untuk Pembaruan dan Penghapusan

Logika untuk menghasilkan perintah secara otomatis untuk pernyataan UPDATE dan DELETE didasarkan pada konkurensi optimis--yaitu, rekaman tidak dikunci untuk pengeditan dan dapat dimodifikasi oleh pengguna atau proses lain kapan saja. Karena rekaman bisa saja dimodifikasi setelah dikembalikan dari pernyataan SELECT, tetapi sebelum pernyataan UPDATE atau DELETE dikeluarkan, pernyataan UPDATE atau DELETE yang dihasilkan secara otomatis berisi klausul WHERE, menentukan bahwa baris hanya diperbarui jika berisi semua nilai asli dan belum dihapus dari sumber data. Ini dilakukan untuk menghindari penimpaan data baru. Jika pembaruan yang dihasilkan secara otomatis mencoba memperbarui baris yang telah dihapus atau yang tidak berisi nilai asli yang ditemukan di DataSet, perintah tidak memengaruhi rekaman apa pun, dan DBConcurrencyException dilemparkan.

Jika Anda ingin PEMBARUAN atau HAPUS selesai terlepas dari nilai aslinya, Anda harus secara eksplisit mengatur UpdateCommand untuk DataAdapter dan tidak mengandalkan pembuatan perintah otomatis.

Batasan Logika Pembuatan Perintah Otomatis

Batasan berikut berlaku untuk pembuatan perintah otomatis.

Tabel Tidak Terkait Saja

Logika pembuatan perintah otomatis menghasilkan pernyataan INSERT, UPDATE, atau DELETE untuk tabel yang berdiri sendiri tanpa mempertimbangkan hubungan apa pun dengan tabel lain di sumber data. Akibatnya, Anda mungkin mengalami kegagalan saat memanggil Update untuk mengirimkan perubahan untuk kolom yang berpartisipasi dalam batasan kunci asing dalam database. Untuk menghindari pengecualian ini, jangan gunakan DbCommandBuilder untuk memperbarui kolom yang terlibat dalam batasan kunci asing; sebaliknya, secara eksplisit tentukan pernyataan yang digunakan untuk melakukan operasi.

Nama Tabel dan Kolom

Logika pembuatan perintah otomatis mungkin gagal jika nama kolom atau nama tabel berisi karakter khusus, seperti spasi, titik, tanda kutip, atau karakter non-alfanumerik lainnya, bahkan jika dibatasi oleh tanda kurung. Bergantung pada penyedia, mengatur parameter QuotePrefix dan QuoteSuffix dapat memungkinkan logika pembuatan memproses ruang, tetapi tidak dapat lolos dari karakter khusus. Nama tabel yang sepenuhnya memenuhi syarat dalam bentuk catalog.schema.table didukung.

Menggunakan CommandBuilder untuk Membuat Pernyataan SQL Secara Otomatis

Untuk secara otomatis menghasilkan pernyataan SQL untuk DataAdapter, pertama-tama atur properti SelectCommanddari DataAdapter, lalu buat objek CommandBuilder, dan tentukan sebagai argumen DataAdapter yang mana CommandBuilder akan secara otomatis menghasilkan pernyataan SQL.

' Assumes that connection is a valid SqlConnection object
' inside of a Using block.  
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _  
  "SELECT * FROM dbo.Customers", connection)  
Dim builder As SqlCommandBuilder = New SqlCommandBuilder(adapter)  
builder.QuotePrefix = "["  
builder.QuoteSuffix = "]"  
// Assumes that connection is a valid SqlConnection object  
// inside of a using block.  
SqlDataAdapter adapter = new SqlDataAdapter(  
  "SELECT * FROM dbo.Customers", connection);  
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);  
builder.QuotePrefix = "[";  
builder.QuoteSuffix = "]";  

Memodifikasi SelectCommand

Jika Anda mengubah CommandText dari SelectCommand setelah perintah INSERT, UPDATE, atau DELETE dibuat secara otomatis, pengecualian dapat terjadi. Jika perintah SelectCommand.CommandText yang dimodifikasi berisi informasi skema yang tidak konsisten dengan SelectCommand.CommandText yang digunakan saat perintah sisipkan, perbarui, atau hapus dibuat secara otomatis, panggilan di masa mendatang ke metode DataAdapter.Update dapat mencoba mengakses kolom yang tidak lagi ada dalam tabel saat ini yang direferensikan oleh SelectCommand, dan pengecualian akan dilemparkan.

Anda dapat merefresh informasi skema yang digunakan oleh CommandBuilder untuk menghasilkan perintah secara otomatis dengan memanggil metode RefreshSchema dari CommandBuilder.

Jika Anda ingin tahu perintah apa yang dibuat secara otomatis, Anda dapat memperoleh referensi ke perintah yang dihasilkan secara otomatis dengan menggunakan metode GetInsertCommand, GetUpdateCommand, dan GetDeleteCommand dari objek CommandBuilder dan memeriksa properti CommandText dari perintah terkait.

Contoh kode berikut menulis ke konsol perintah pembaruan yang dibuat secara otomatis.

Console.WriteLine(builder.GetUpdateCommand().CommandText)  
Console.WriteLine(builder.GetUpdateCommand().CommandText);

Contoh berikut membuat ulang tabel Customers dalam himpunan data custDS. Metode RefreshSchema dipanggil untuk menyegarkan perintah yang dihasilkan secara otomatis dengan informasi kolom baru ini.

' Assumes an open SqlConnection and SqlDataAdapter inside of a Using block.  
adapter.SelectCommand.CommandText = _  
  "SELECT CustomerID, ContactName FROM dbo.Customers"  
builder.RefreshSchema()  
  
custDS.Tables.Remove(custDS.Tables("Customers"))  
adapter.Fill(custDS, "Customers")  
// Assumes an open SqlConnection and SqlDataAdapter inside of a using block.  
adapter.SelectCommand.CommandText =
  "SELECT CustomerID, ContactName FROM dbo.Customers";  
builder.RefreshSchema();  
  
custDS.Tables.Remove(custDS.Tables["Customers"]);  
adapter.Fill(custDS, "Customers");  

Lihat juga