日期:2014-05-20  浏览次数:20912 次

请教一下DBNull.value的真正含义是什么?
看一篇很权威的文章说ADO.NET中的SqlCommand对象执行executeScalar()方法,如果数据库中对应的值是null,则返回DBNul.value.但我调试了一下,返回值却是 " ".我用==相比较,发现DBNul.value与返回值也不相等?
我像请教一下DBNull.value的真正含义是什么?

------解决方案--------------------
DBNull.value的真正含义是什么?
======
该类用于指示不存在某个已知值(通常在数据库应用程序中)。

在数据库应用程序中,空对象是字段的有效值。该类区分空值(空对象)和未初始化值(DBNull.Value 实例)。例如,表可以包含具有未初始化字段的记录。默认情况下,这些未初始化字段具有 DBNull 值。

该类还可以用于在 COM Interop 中区分 VT_NULL 变量(与空对象关联)和 VT_EMPTY 变量(与 DBNull.Value 实例关联)。

DBNull 从不等于任何值。// .NET 中不等于任何非 DBNull 的值

DBNull 是一个单独的类,这意味着该类只能存在一个实例。这个唯一的实例是 DBNull.Value。


但我调试了一下,返回值却是 " "
======
事实上,此时你看到的是调用 DBNull 实例的 ToString() 方法的结果,此方法返回空字符串(String.Empty)。


我用==相比较,发现DBNul.value与返回值也不相等?

用equals()相比较也不相等!
======

怀疑 LZ 测试结果的正确性,不知 LZ 是如何测试代码?

因为 ->

如上所述,DBNull 的意义与数据库中的 NULL 类似,表示未知值,

在数据库中,NULL 的相等比较运算,必须使用 IS 运算(按 ANSI-SQL 规范,任何与数据与 NULL 进行运算结果都是 NULL,除了 IS,即使两个 NULL 之间用 = ,也不例外)

NULL = NULL -- false
NULL IS NULL -- true

然而,对于相等运算,在 NET 中,DBNull 不遵循此规则,DBNull 与自身任何实例(事实上只有一个实例即 DBNull.Value )进行 【相等】比较,不管是 Equals 方法,还是特定语言的比较符(C# 中为 ==),均返回 true,因为 DBNull.Equals 方法直接继承自 Object.Equals ,而后者内部实现为【引用比较】,即只要两个引用指向同一个对象实例则相等,
那么因为只存在一个 DBNull 实例(DBNull.Value),自然任何时候都相等

测试代码:

// 环境 Windows XP SP2 + .NET 2.0
HtmlPreWriter writer = new HtmlPreWriter();

// 以下输出均为 False
object result = null;
writer.WriteLine(DBNull.Value == result);
writer.WriteLine(DBNull.Value.Equals(result));
writer.WriteLine(Object.Equals(DBNull.Value, result));
writer.WriteLine(Object.ReferenceEquals(DBNull.Value, result));
result = "hello ";
writer.WriteLine(DBNull.Value == result);
writer.WriteLine(DBNull.Value.Equals(result));
writer.WriteLine(Object.Equals(DBNull.Value, result));
writer.WriteLine(Object.ReferenceEquals(DBNull.Value, result));

writer.WriteLine();

// 以下输出均为 True
writer.WriteLine(DBNull.Value.Equals(DBNull.Value));
writer.WriteLine(DBNull.Value == DBNull.Value);

using (SqlConnection conn = new SqlConnection( "server=.;database=Northwind;uid=sa; ")) {
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT TOP 1 Region FROM Customers WHERE Region IS NULL ";
result = cmd.ExecuteScalar(); // 返回 NULL
writer.WriteLine(DBNull.Value == result);
writer.WriteLine(DBNull.Value.Equals(result));
writer.WriteLine(Object.Equals(DBNull.Value, result));
writer.WriteLine(Object.ReferenceEquals(DBNull.Value, result));
writer.WriteLine(Convert.IsDBNull(result));
//
writer.WriteLine(result.GetType() == typeof(DBNull));
writer.WriteLine(result is DBNull);
}

//
writer.Flush();