C# null和System.DBNull.Value之间有什么区别?
null和System.DBNull.Value之间有什么区别吗?如果是,是什么 我现在注意到了这种行为-C# null和System.DBNull.Value之间有什么区别?,c#,null,dbnull,C#,Null,Dbnull,null和System.DBNull.Value之间有什么区别吗?如果是,是什么 我现在注意到了这种行为- while (rdr.Read()) { if (rdr["Id"] != null) //if (rdr["Id"] != System.DBNull.Value) { int x = Convert.ToInt32(rdr["Id"]); } } 虽然我使用sql datareader从数据库中检索数据,但是如果(rdr[“Id”!=nul
while (rdr.Read())
{
if (rdr["Id"] != null) //if (rdr["Id"] != System.DBNull.Value)
{
int x = Convert.ToInt32(rdr["Id"]);
}
}
虽然我使用sql datareader从数据库中检索数据,但是如果(rdr[“Id”!=null)没有返回值if
返回true
,并最终抛出将null转换为整数的异常
但是,如果我使用if(rdr[“Id”!=System.DBNull.Value)
返回false
null和System.DBNull.Value之间有什么区别 DBNull.Value是.NET数据库提供程序返回的值,表示数据库中的空条目。DBNull.Value不为null,并且对于从数据库行检索到的列值,将其与null进行比较将不起作用,您应该始终与DBNull.Value进行比较
嗯,
null
不是任何类型的实例。相反,它是一个无效的引用
但是,System.DbNull.Value
是对System.DbNull
实例的有效引用(System.DbNull
是一个单例,System.DbNull.Value
提供对该类的单个实例的引用),该实例表示数据库中不存在的*值
*我们通常会说null
,但我不想混淆这个问题
所以,两者在概念上有很大的区别。关键字null
表示无效引用。类System.DbNull
表示数据库字段中不存在的值。一般来说,我们应该尽量避免使用相同的东西(在本例中为null
)来表示两个非常不同的概念(在本例中为无效引用,而不是数据库字段中不存在的值)
请记住,这就是为什么很多人提倡通常使用,这正是
系统的一个例子。DbNull
就是一个例子。DataRow有一个名为IsNull()
的方法,您可以使用该方法来测试列是否有空值-关于数据库看到的空值
DataRow[“col”]==null
将始终为false
使用
相反。Null类似于C++中的零指针。因此,它是一个不指向任何值的引用
DBNull.Value
完全不同,是一个常量,当字段值包含NULL时返回。来自以下文档:
不要将面向对象编程语言中的null概念与DBNull对象混淆。在面向对象编程语言中,null表示没有对对象的引用。DBNull表示未初始化的变量或不存在的数据库列
必须处理的DBNull.Value很烦人 我使用静态方法检查它是否为DBNull,然后返回值
SqlDataReader r = ...;
String firstName = getString(r[COL_Firstname]);
private static String getString(Object o) {
if (o == DBNull.Value) return null;
return (String) o;
}
另外,在将值插入数据行时,不能使用“null”,必须使用DBNull.Value
“null”有两个表示形式是一个糟糕的设计,没有明显的好处。嗯,它们是不相关的。一个是
System.Data
中类的静态实例,另一个是表示缺少引用的特殊值。他们彼此无关。你能详细说明你对什么感到困惑吗?你真正的问题是“为什么DataRows
和DataReaders
将DBNull.Value
放在它们自己内部而不是null
?”嗯,我的问题不是最初的问题,但从你说的话中学习之后,我很好奇。你能告诉我为什么DataRows和DataReader将DBNull.Value放在它们自己而不是null中吗?我自己也不确定。这里有一个答案:也有可能在C#中出现可空值类型之前,处理null
会更麻烦。我在这里有一个答案,但我意识到它更适合-所以我移动了itp.s。还应使用DBNull.Value将null参数传递给数据库,否则可能会将其解释为未传递参数。DBNull不是“数据库返回的内容”-它只是ADO.NET选择的解释方式;就我个人而言,我不确定这种解释是否非常正确valuable@MarcGravell是的,马克,你说得对。我用词不对。ASP.NET将数据库null列值转换为DBNull.value+1一个实际示例:如果使用IDbCommand.ExecuteScalar()
,它可以返回null(未返回任何记录)或DBNull
(第一条记录中的第一列是“不存在的值”)。如果没有DbNull
您将无法区分两者。我强烈建议您使用一种禁止使用Null的语言,并且这样做的成本绝对为零。生命对于“空对象模式”来说太短,空引用是完全有效的。☺@当然,还有另一个常见的建议:函数应该只返回一种类型的值。这就是为什么人们更喜欢类型良好的打字脚本代码。“执行状态”与“计算结果”不同。他们可能已经决定以其他方式实现此功能(可能是一个out参数,或者类似于HTTP请求-响应objs的对象)。当然,这不是一个真正想要的复杂问题,但如果他们这样做了,也许可以使用null来代替DbNull。我们共同的厌恶情绪是:你的上一句话只是被出现在这里阅读这篇文章并发现你的用户名是“讨厌”的讽刺所压倒
SqlDataReader r = ...;
String firstName = getString(r[COL_Firstname]);
private static String getString(Object o) {
if (o == DBNull.Value) return null;
return (String) o;
}