2011-02-10 85 views
71

Có sự khác biệt nào giữa null và System.DBNull.Value không? Nếu có, nó là cái gì?Sự khác nhau giữa null và System.DBNull.Value là gì?

tôi nhận thấy hành vi này ngay bây giờ -

while (rdr.Read()) 
{ 
    if (rdr["Id"] != null) //if (rdr["Id"] != System.DBNull.Value) 
    { 
     int x = Convert.ToInt32(rdr["Id"]); 
    } 
} 

Trong khi tôi lấy dữ liệu từ cơ sở dữ liệu sử dụng một datareader sql, mặc dù không có giá trị trả về if(rdr["Id"] != null) trở true và cuối cùng ném một ngoại lệ cho đúc một null như số nguyên.

Nhưng, điều này nếu tôi sử dụng if (rdr["Id"] != System.DBNull.Value) trả lại false.

Sự khác nhau giữa null và System.DBNull.Value là gì?

+0

Vâng, chúng không liên quan. Một là một thể hiện tĩnh của một lớp trong 'System.Data', và một là một giá trị đặc biệt biểu thị sự thiếu tham chiếu. Họ không có gì để làm với nhau. Bạn có thể giải thích về những gì bạn đang bối rối không? Là câu hỏi thực sự của bạn "tại sao' DataRows' và 'DataReaders' đặt' DBNull.Value' bên trong bản thân thay vì 'null'?" – mquander

+0

Vâng, tôi không phải lúc đầu nhưng sau khi học hỏi từ những gì bạn nói, tôi tò mò. Bạn có thể cho tôi biết tại sao DataRows và DataReaders đặt DBNull.Value vào bản thân thay vì null? – pavanred

+0

Tôi không chắc chắn bản thân mình. Đây là một câu trả lời: http://stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull/4488758#4488758 Cũng có thể là trước khi các kiểu giá trị rỗng có trong C#, nó sẽ có nhiều hơn một rắc rối để đối phó với 'null'. – mquander

Trả lời

89

Vâng, null không phải là một thể hiện của bất kỳ loại. Thay vào đó, nó là một tham chiếu không hợp lệ.

Tuy nhiên, System.DbNull.Value, là một tài liệu tham khảo có giá trị cho một thể hiện của System.DbNull (System.DbNull là một singleton và System.DbNull.Value mang đến cho bạn một tham chiếu đến các trường hợp duy nhất của lớp đó) mà đại diện không tồn tại * giá trị trong cơ sở dữ liệu.

* Thông thường chúng tôi sẽ nói null, nhưng tôi không muốn gây nhầm lẫn vấn đề.

Vì vậy, có sự khác biệt lớn giữa hai khái niệm. Từ khóa null đại diện cho tham chiếu không hợp lệ. Lớp System.DbNull đại diện cho một giá trị không tồn tại trong một trường cơ sở dữ liệu. Nói chung, chúng ta nên tránh sử dụng cùng một điều (trong trường hợp này là null) để biểu diễn hai khái niệm rất khác nhau (trong trường hợp này là một tham chiếu không hợp lệ so với một giá trị không tồn tại trong một trường cơ sở dữ liệu).

Xin lưu ý, đây là lý do tại sao nhiều người ủng hộ bằng cách sử dụng null object pattern nói chung, chính xác là những gì System.DbNull là một ví dụ về.

+31

+1 Ví dụ thực tế: nếu bạn sử dụng 'IDbCommand.ExecuteScalar()', nó có thể trả về null (không có bản ghi nào được trả về) hoặc 'DbNull' (cột đầu tiên trong bản ghi là 'giá trị không tồn tại'). Nếu không có 'DbNull', bạn sẽ không thể phân biệt cái này với cái kia. –

+0

Tôi thực sự khuyên bạn nên sử dụng một ngôn ngữ cấm sử dụng Null, và làm như vậy với chi phí tối đa là 0. cuộc sống quá ngắn đối với "mẫu đối tượng null" – nicolas

+2

Tham chiếu null là hoàn toàn hợp lệ. ☺ – IllidanS4

5

DBNull.Value là những gì các nhà cung cấp cơ sở dữ liệu .NET trở về đại diện cho một mục nhập rỗng trong cơ sở dữ liệu. DBNull.Value không phải là null và so sánh với null cho các giá trị cột được lấy từ một hàng cơ sở dữ liệu sẽ không hoạt động, bạn nên luôn luôn so sánh với DBNull.Value.

http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx

+0

p.s. Bạn cũng nên sử dụng DBNull.Value để truyền một tham số null vào cơ sở dữ liệu, nếu không nó có thể được diễn giải khi tham số không được chuyển. –

+0

DBNull là * không * "những gì cơ sở dữ liệu trả về" - nó chỉ đơn giản là cách ADO.NET chọn để giải thích nó; cá nhân tôi không chắc chắn rằng cách giải thích này rất có giá trị –

+0

@MarcGravell Có, Marc, bạn là chính xác. Tôi đã nói không chính xác. ASP.NET dịch giá trị cột null của cơ sở dữ liệu sang DBNull.Value –

3

DataRow có phương thức được gọi là IsNull() mà bạn có thể sử dụng để kiểm tra cột nếu nó có giá trị null - liên quan đến giá trị null khi cơ sở dữ liệu nhìn thấy.

DataRow["col"]==null allways là false.

sử dụng

DataRow r; 
if (r.IsNull("col")) ... 

để thay thế.

2

Null tương tự như số không trong C++. Đó là tham chiếu không trỏ đến bất kỳ giá trị nào.

DBNull.Value hoàn toàn khác và là hằng số được trả lại khi giá trị trường chứa NULL.

20

Từ các tài liệu của DBNull class:

Đừng nhầm lẫn giữa khái niệm về null trong một ngôn ngữ lập trình hướng đối tượng với một đối tượng DBNull. Trong một ngôn ngữ lập trình hướng đối tượng, null có nghĩa là không có tham chiếu đến một đối tượng. DBNull đại diện cho một biến thể chưa được khởi tạo hoặc cột cơ sở dữ liệu không tồn tại.

8

DBNull.Value khó chịu phải giải quyết.

Tôi sử dụng các phương pháp tĩnh để kiểm tra xem đó là DBNull và sau đó trả về giá trị.

SqlDataReader r = ...; 
String firstName = getString(r[COL_Firstname]); 

private static String getString(Object o) { 
    if (o == DBNull.Value) return null; 
    return (String) o; 
} 

Ngoài ra, khi chèn giá trị vào DataRow, bạn không thể sử dụng "null", bạn phải sử dụng DBNull.Value.

Có hai biểu diễn "null" là thiết kế không có lợi ích rõ ràng.

Các vấn đề liên quan