Có rất nhiều câu trả lời ở đây với thông tin hữu ích (và một số thông tin sai) được lan truyền, tôi muốn kết hợp tất cả lại với nhau.
Câu trả lời ngắn cho câu hỏi là kiểm tra DBNull - hầu như mọi người đều đồng ý với bit này :)
Thay vì sử dụng một phương thức trợ giúp để đọc các giá trị null cho mỗi kiểu dữ liệu SQL, một phương thức chung cho phép chúng tôi giải quyết vấn đề này với ít mã hơn. Tuy nhiên, bạn không thể có một phương thức chung duy nhất cho cả loại giá trị null và loại tham chiếu, điều này được thảo luận ở độ dài trong
loại Nullable như một tham số chung có thể? và ràng buộc kiểu chung C # cho mọi thứ nullable .
Vì vậy, tiếp theo các câu trả lời từ @ZXX và @getpsyched, chúng tôi kết thúc với phương pháp này, 2 phương pháp để nhận các giá trị null và tôi đã thêm một thứ 3 cho các giá trị không null (nó hoàn thành bộ dựa trên cách đặt tên phương thức).
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);
}
Tôi thường sử dụng tên cột, thay đổi chúng nếu bạn sử dụng chỉ mục cột. Dựa trên các tên phương thức này, tôi có thể biết liệu tôi có mong đợi dữ liệu là null hay không, khá hữu ích khi xem mã được viết từ lâu.
Lời khuyên;
- Không có cột nullable trong cơ sở dữ liệu sẽ tránh được vấn đề này. Nếu bạn có quyền kiểm soát cơ sở dữ liệu thì các cột sẽ không phải là null theo mặc định và chỉ có thể là null khi cần thiết.
- Không truyền các giá trị cơ sở dữ liệu với toán tử C # 'as' vì nếu truyền sai, nó sẽ âm thầm trả về null.
- Sử dụng biểu thức giá trị mặc định sẽ thay đổi null cơ sở dữ liệu thành giá trị không null cho các loại giá trị như int, datetime, bit, v.v.
Cuối cùng, trong khi thử nghiệm các phương thức trên trên tất cả các loại dữ liệu SQL Server, tôi phát hiện ra rằng bạn không thể trực tiếp nhận được char [] từ SqlDataReader, nếu bạn muốn có char [], bạn sẽ phải lấy một chuỗi và sử dụng ToCharArray ().
int colIndex = reader.GetOrdinal(fieldname);
và dễ dàng quá tảiSafeGetString
chức năng của @ marc_s .