Apa yang terjadi di sana?
Anda mengutip daftar parameter untuk beberapa kelebihan Add
. Ini adalah metode praktis yang berhubungan langsung dengan kelebihan konstruktor untuk SqlParameter
kelas. Mereka pada dasarnya membangun objek parameter menggunakan konstruktor apa pun yang memiliki tanda tangan yang sama dengan metode praktis yang Anda panggil, dan kemudian memanggil SqlParameterCollection.Add(SqlParameter)
seperti ini:
SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);
AddWithValue
serupa tetapi membutuhkan kenyamanan lebih jauh, juga mengatur nilainya. Namun, itu sebenarnya diperkenalkan untuk menyelesaikan cacat kerangka kerja. Mengutip MSDN,
Kelebihan
Add
yang mengambil astring dan objek tidak digunakan lagi karena kemungkinan ambiguitas denganSqlParameterCollection.Add
kelebihan yang membutuhkanString
danSqlDbType
nilai enumerasi di mana melewatkan bilangan bulat dengan string dapat ditafsirkan sebagai nilai parameter atauSqlDbType
yang sesuai nilai. GunakanAddWithValue
kapan pun Anda ingin menambahkan parameter dengan menentukan nama dan nilainya.
Konstruktor kelebihan beban untuk SqlParameter
class hanyalah kemudahan untuk mengatur properti instance. Mereka mempersingkat kode, dengan dampak kecil pada kinerja:konstruktor dapat melewati metode penyetel dan beroperasi langsung pada anggota pribadi. Kalaupun ada perbedaannya tidak akan banyak.
Apa yang harus saya lakukan?
Perhatikan yang berikut (dari MSDN)
Untuk parameter dua arah dan keluaran, dan mengembalikan nilai, Anda harus menyetel nilai
Size
. Ini tidak diperlukan untuk parameter input, dan jika tidak disetel secara eksplisit, nilai disimpulkan dari ukuran sebenarnya dari parameter yang ditentukan saat pernyataan berparameter dijalankan.
Jenis default adalah masukan. Namun, jika Anda mengizinkan ukuran untuk disimpulkan seperti ini dan Anda mendaur ulang objek parameter dalam satu lingkaran (Anda memang mengatakan Anda khawatir dengan kinerja) maka ukuran akan ditetapkan oleh nilai pertama dan nilai berikutnya yang lebih panjang akan menjadi terpotong. Jelas ini hanya signifikan untuk nilai panjang variabel seperti string.
Jika Anda melewati parameter logis yang sama berulang kali dalam satu lingkaran, saya sarankan Anda membuat objek SqlParameter di luar loop dan mengukurnya dengan tepat. Ukuran varchar yang terlalu besar tidak berbahaya, jadi jika itu adalah PITA untuk mendapatkan maksimum yang tepat, atur saja lebih besar dari yang Anda harapkan kolomnya. Karena Anda mendaur ulang objek daripada membuat yang baru untuk setiap iterasi, konsumsi memori selama durasi loop kemungkinan akan turun bahkan jika Anda sedikit tertarik dengan ukuran yang terlalu besar.
Sejujurnya, kecuali Anda memproses ribuan panggilan, semua ini tidak akan membuat banyak perbedaan. AddWithValue
menciptakan objek baru, menghindari masalah ukuran. Ini singkat dan manis dan mudah dimengerti. Jika Anda mengulang ribuan, gunakan pendekatan saya. Jika tidak, gunakan AddWithValue
untuk menjaga agar kode Anda tetap sederhana dan mudah dirawat.
2008 sudah lama sekali
Selama bertahun-tahun sejak saya menulis ini, dunia telah berubah. Ada jenis tanggal baru, dan ada juga masalah yang tidak terlintas dalam pikiran saya sampai masalah baru-baru ini dengan tanggal membuat saya berpikir tentang implikasi dari pelebaran.
Pelebaran dan penyempitan, bagi mereka yang tidak terbiasa dengan istilah tersebut, adalah kualitas dari konversi tipe data. Jika Anda menetapkan int ke double, tidak ada kehilangan presisi karena double "lebih lebar". Itu selalu aman untuk melakukan ini, jadi konversi otomatis. Inilah sebabnya mengapa Anda dapat menetapkan int ke dobel tetapi sebaliknya Anda harus melakukan pemeran eksplisit - double ke int adalah konversi yang menyempit dengan potensi kehilangan presisi.
Ini dapat berlaku untuk string:NVARCHAR lebih lebar dari VARCHAR, jadi Anda dapat menetapkan VARCHAR ke NVARCHAR tetapi sebaliknya membutuhkan pemeran. Perbandingan berfungsi karena VARCHAR secara implisit melebar ke NVARCHAR, tetapi ini akan mengganggu penggunaan indeks!
String C# adalah Unicode, jadi AddWithValue akan menghasilkan parameter NVARCHAR. Di ujung lain, nilai kolom VARCHAR melebar ke NVARCHAR untuk perbandingan. Ini tidak menghentikan eksekusi kueri tetapi mencegah indeks digunakan. Ini buruk.
Apa yang dapat Anda lakukan? Anda memiliki dua kemungkinan solusi.
- Ketik parameter secara eksplisit. Ini berarti tidak ada lagi AddWithValue
- Ubah semua jenis kolom string ke NVARCHAR.
Membuang VARCHAR mungkin adalah ide terbaik. Ini adalah perubahan sederhana dengan konsekuensi yang dapat diprediksi dan meningkatkan cerita pelokalan Anda. Namun, Anda mungkin tidak memiliki ini sebagai opsi.
Hari-hari ini saya tidak melakukan banyak ADO.NET langsung. Linq2Sql sekarang menjadi senjata pilihan saya, dan tindakan menulis pembaruan ini membuat saya bertanya-tanya bagaimana cara menangani masalah ini. Saya tiba-tiba memiliki keinginan yang membara untuk memeriksa kode akses data saya untuk pencarian melalui kolom VARCHAR.
2019 dan dunia telah bergerak lagi
Linq2Sql tidak tersedia di dotnet Core, jadi saya menggunakan Dapper. Masalah [N]VARCHAR masih menjadi masalah tetapi tidak lagi terkubur sejauh ini. Saya percaya seseorang juga dapat menggunakan ADO sehingga semuanya menjadi lingkaran penuh dalam hal itu.