Ada banyak jawaban di sini dengan info berguna (dan beberapa info salah) tersebar, saya ingin menggabungkan semuanya.
Jawaban singkat untuk pertanyaan ini adalah untuk memeriksa DBNull - hampir semua orang setuju pada bagian ini :)
Daripada menggunakan metode pembantu untuk membaca nilai nullable per tipe data SQL metode generik memungkinkan kita untuk mengatasi ini dengan kode yang jauh lebih sedikit. Namun, Anda tidak dapat memiliki metode generik tunggal untuk tipe nilai nullable dan tipe referensi, ini dibahas panjang lebar dalam
tipe Nullable sebagai parameter generik yang mungkin? dan batasan tipe generik C # untuk semua yang dapat dibatalkan .
Jadi, sebagai lanjutan dari jawaban dari @ZXX dan @getpsyched kita berakhir dengan ini, 2 metode untuk mendapatkan nilai nullable dan saya telah menambahkan 3 untuk nilai-nilai non-null (melengkapi set berdasarkan metode penamaan).
public static T? GetNullableValueType<T>(this SqlDataReader sqlDataReader, string columnName) where T : struct
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.IsDBNull(columnOrdinal) ? (T?)null : sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
public static T GetNullableReferenceType<T>(this SqlDataReader sqlDataReader, string columnName) where T : class
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.IsDBNull(columnOrdinal) ? null : sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
public static T GetNonNullValue<T>(this SqlDataReader sqlDataReader, string columnName)
{
int columnOrdinal = sqlDataReader.GetOrdinal(columnName);
return sqlDataReader.GetFieldValue<T>(columnOrdinal);
}
Saya biasanya menggunakan nama kolom, ubah ini jika Anda menggunakan indeks kolom. Berdasarkan nama-nama metode ini saya bisa tahu apakah saya mengharapkan data menjadi nullable atau tidak, cukup berguna ketika melihat kode yang ditulis sejak lama.
Kiat;
- Tidak memiliki kolom yang dapat dibatalkan dalam basis data menghindari masalah ini. Jika Anda memiliki kontrol atas database maka kolom harus non-null secara default dan hanya nullable jika diperlukan.
- Jangan memberikan nilai basis data dengan operator C # 'sebagai' karena jika gips salah maka diam-diam akan mengembalikan nol.
- Menggunakan ekspresi nilai default akan mengubah basis data nol menjadi nilai bukan nol untuk jenis nilai seperti int, datetime, bit dll.
Terakhir, saat menguji metode di atas di semua tipe data SQL Server saya menemukan Anda tidak bisa langsung mendapatkan char [] dari SqlDataReader, jika Anda ingin char [] Anda harus mendapatkan string dan menggunakan ToCharArray ().
int colIndex = reader.GetOrdinal(fieldname);
dan dengan mudah membebaniSafeGetString
fungsi @ marc_s .