我正在寻找一些.net程序的代码,我正在处理。该程序的前一作者在一年前向我提供了代码。突然,我看到从代码中抛出的异常,我没有感动:关于空字符串和DBNull的困惑
if ((string)row["LevelName"] != "ABC")
唯一的例外是“无法投类型的对象'System.DBNull为键入‘System.String’
。我认为字符串是一个可空数据类型,所以我怎么可能会得到这个异常
我正在寻找一些.net程序的代码,我正在处理。该程序的前一作者在一年前向我提供了代码。突然,我看到从代码中抛出的异常,我没有感动:关于空字符串和DBNull的困惑
if ((string)row["LevelName"] != "ABC")
唯一的例外是“无法投类型的对象'System.DBNull为键入‘System.String’
。我认为字符串是一个可空数据类型,所以我怎么可能会得到这个异常
DBNull是它自己的类,它包含itsself在一个名为Value属性singleton实例。 DBNull.Value不等于null,因为它是对此类的实例的引用。
如果没有值,大多数(即使不是全部)数据库包装将返回DBNull.Value
而不是null
。其中一个原因是因为返回一个真实的null
可能意味着根本不存在任何行,而不仅仅是列中的空值(这取决于您使用哪些对象来获取值)。
通常,as运算符对于DBNull
非常有用,可以与任何可空类型(包括string
)一起使用。
string str = reader["Name"] as string;
int? i = reader["Age"] as int?;
这也可能是值得一提的是,??运营商是非常有用的也在这里,当你需要一个非空值类型(虽然它不看太漂亮)。
int i = reader["Age"] as int? ?? -1;
我发现这很方便,因为它是LINQ select子句中的一件小事。
我相信你要找的是什么?
if ((row["LevelName"] as String) != "ABC")
没有隐式转换DBNull和String之间。
它可能以前工作过,因为刚好在您的数据库中该列中没有NULL。也许有些数据被破坏,或者有人在表上改变了NOT NULL约束。
基本上,如果您明确施放了某些东西,最好确保它们具有兼容的动态类型,否则会抛出异常。 as
操作员基本上说“如果可能的话将其转换为此值,否则逻辑值为空。”显然,as
运算符只能用于引用类型,因为结构不能为空。
你的答案暗示了这一点,但值得说明的是:在使用显式类型转换'(Type)变量'会导致'InvalidCastException'的情况下,使用'variable as Type'将产生'null'。 – Rob
.NET null
与DBNull.Value
之间存在差异。在这里,您可以看到类DBNull
和该类的Value字段。
你应该能够做这样的事情:
if (row["LevelName"].Value == DBNull.Value)
return false;
else if (row["LevelName"].ToString() != "ABC")
// do something
// ....
DBNull表示数据库中的空值。这与.NET null不同,它表示一个空引用。
代码突然失败,因为有人更改或插入了空白的记录。
是的,字符串可以为空,但是您将一个dbnull投射到字符串。您必须检查dbnull,如果它存在,则将其替换为null。
DBNull表示在给定的数据库列中没有数据。如果在数据库中创建新记录,但没有将值分配给“LevelName”列,则会发生这种情况。
DBNull与空对象引用或空字符串变量不同。 DBNull表示列数据从未设置。如果您为“LevelName”列指定一个空值,那么该列已经初始化并且它将返回null(而不是DBNull)。
此代码已运行良好超过一年;我觉得我一定在某个地方弄错了什么 –
是的,事实上,我做到了。有问题的代码没有准备好DBNull值,因为它永远不会出现在我正在运行的特定查询中。我在修改查询时犯了一个错误,因此错误出现了。 –
感谢您提供丰富的答案,每个人。我把它们都投了票。难怪我读的SQL书叫NULL“四个字母的单词”。 –