Câu hỏi Sự khác nhau giữa null và System.DBNull.Value là gì?


Có bất kỳ sự khác biệt giữa null và System.DBNull.Value? Nếu có, nó là cái 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 bằng cách sử dụng một bộ dữ liệu sql, mặc dù không có giá trị trả về if(rdr["Id"] != null) trả lại true và cuối cùng đã ném một ngoại lệ cho việc đúc một số nguyên rỗng.

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

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


76
2018-02-10 14:33


gốc


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.Datavà một là 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
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
Tôi không chắc chắn bản thân mình. Đây là một câu trả lời: stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull/… Nó cũng có thể là trước khi các kiểu giá trị nullable được xung quanh trong C #, nó sẽ có nhiều rắc rối hơn để xử lý null. - mquander
Tôi có câu trả lời ở đây, nhưng tôi nhận ra câu trả lời phù hợp hơn stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull - vì vậy tôi đã di chuyển nó - Marc Gravell♦


Các câu trả lời:


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

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

* Chúng tôi thường nói nullnhưng tôi không muốn làm phiền vấn đề.

Vì vậy, có một sự khác biệt lớn về khái niệm giữa hai người. 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 cố gắng tránh sử dụng cùng một điều (trong trường hợp này null) đại diện cho 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 mẫu đối tượng rỗng nói chung, đó là chính xác những gì System.DbNull là một ví dụ về.


95
2018-02-10 14:36



+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ả lại) hoặc DbNull (cột đầu tiên trong bản ghi đầu tiên là 'giá trị không tồn tại'). Không có DbNull bạn sẽ không thể phân biệt cái này với cái kia. - C.Evenhuis
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 rỗng" - nicolas
Một tham chiếu null là hoàn toàn hợp lệ. - IllidanS4


Từ tài liệu của Lớp DBNull:

Đừng nhầm lẫn khái niệm null trong ngôn ngữ lập trình hướng đối tượng với đố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.


20
2018-02-10 14:38





DBNull.Value là khó chịu để phải đối phó với.

Tôi sử dụng 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 một 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 của "null" là một thiết kế xấu không có lợi ích rõ ràng.


9
2018-06-25 22:34





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


5
2018-02-10 14:35



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. - James Michael Hare
DBNull là không phải "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 rằng cách giải thích này rất có giá trị - Marc Gravell♦
@ 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 - James Michael Hare


DataRow có một 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 null khi nó được cơ sở dữ liệu nhìn thấy.

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

sử dụng

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

thay thế.


3
2018-02-10 14:37





Null tương tự như con trỏ bằng không trong C ++. Vì vậy, nó là một tham chiếu không trỏ đến bất kỳ giá trị nào.

DBNull.Value hoàn toàn khác và là không thay đổi được trả về khi giá trị trường chứa NULL.


3
2018-02-10 14:38