12

当我的网站进入以下代码时,它会出现以下异常:

System.InvalidCastException:对象不能从 DBNull 转换为其他类型。

为简洁起见,我只展示了相关代码(这是我得到的 4000+ LOC 文件)。

if (dr["STAGE"] is DBNull)
{
    dto.Stage = 1; // This is the line throwing the exception, according to stack trace
}
else
{
    dto.Stage = Convert.ToInt32(dr["STAGE"]);
}

在这里,dr是一个 DataRow 对象,它是对数据库的查询结果,dto是一个只包含一些属性的基本类,它是其中dto.Stage的一个int成员。

我查看了具有相同错误消息的其他问题,但其中大多数似乎建议“检查它是否为 DBNull”,我已经在这样做了。

那么有人可以提出解决方案吗?

4

5 回答 5

5

使用==代替is

if (dr["STAGE"] == DBNull.Value)
{

}
于 2012-06-26T14:13:23.597 回答
2

使用这种稍微更有效的方法

int stageOrdinal = dr.GetOrdinal("STAGE");
while (dr.Read()) {
     dto = new DataTransferObject();
     if (dr.IsDBNull(stageOrdinal)) {
         dto.Stage = 1;
     } else {
         dto.Stage = dr.GetInt32(stageOrdinal);
     }
     //TODO: retrieve other columns.
     dtoList.Add(dto);
}

按索引访问列比按名称访问要快。可以使用 的GetOrdinal方法检索列的索引DataReader。这最好在循环之前完成。

于 2012-06-26T14:19:48.420 回答
1

请改用System.Data.DataRow.IsNull函数。

if(dr.IsNull("Stage"))
{
 ...
}
于 2012-06-26T14:14:09.963 回答
0

下面是一个可空数据类型的示例,您可以使用它来避免 DBNull 错误。下面的示例不是您遇到的问题的真正解决方案,而是您如何解决问题的示例。把它想象成学习钓鱼,而不是被给予一条鱼。

我从http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx中提取了这个

class NullableExample
{
    static void Main()
    {
        int? num = null;
        if (num.HasValue == true)
        {
            System.Console.WriteLine("num = " + num.Value);
        }
        else
        {
            System.Console.WriteLine("num = Null");
        }

        // y is set to zero
        int y = num.GetValueOrDefault();

        // num.Value throws an InvalidOperationException if num.HasValue is false
        try
        {
            y = num.Value;
        }
        catch (System.InvalidOperationException e)
        {
            System.Console.WriteLine(e.Message);
        }
    }
}
于 2012-06-26T14:23:40.620 回答
0

@MarcGravell 在他的评论中有权利:

忽略堆栈跟踪中的确切行号;数字可能会略有偏差-我一直都看到。而是在带有断点的调试器中运行它,或者在确定它的同时添加额外的日志记录

@Sergey 的回答完全是错误的。

于 2012-08-07T10:05:40.673 回答