2

How come I get an invalid cast exception when trying to set a NULL value returned from the database inside Comments which is of type Int32.

I am trying to replace this:

                try
                {
                    objStreamItem.Comments = (Int32)sqlReader["Comments"];
                    if (objStreamItem.Comments > 0) { 
                        listComments = Comment.GetAll(objStreamItem.Id);

                    }
                }
                catch (InvalidCastException)
                {
                    // Execute if "Comments" returns NULL
                    listComments = null;
                    objStreamItem.Comments = 0;
                }

With this:

Comments = ((Int32?)sqlReader["Comments"]) ?? 0

The two are in different contexts, but you should get the idea. Instead of using a try catch block I am trying to solve this in a more elegant way.

Thanks.

UPDATE

It is stored as a nullable integer in the database.

    public int? Comments
    {
        get;
        set;
    }

I just want to thank everyone who answered or posted on this question, everything was very informative. thanks!

4

4 回答 4

7

DBNull当值为 null 时,您的 SQL 阅读器正在返回;没有从DBNullto的转换int?,并且空合并运算符不识别DBNull.Value为需要合并的东西。

编辑 3

GetAll()(原始代码的另一个问题:如果“Comments”不为空但抛出. ,它将假定“Comments”返回 null InvalidCastException。)

正如 hvd 指出的那样,您可以将 as 运算符与可为空的类型一起使用:

objStreamItem.Comments = sqlReader["Comments"] as int?;
listComments = (objStreamItem.Comments ?? 0) > 0 ? Comment.GetAll(objStreamItem.ID) : null;

但是,如果您只是定义Comment.GetAll()为在传递给它的 ID 没有注释时返回空列表或空引用,则您可以避免所有这些。

于 2011-12-27T18:55:30.370 回答
2

我想三元表达式是去这里的方式

objStreamItem.Comments = sqlReader["Comments"] is DBNull ? 0 : (Int32)sqlReader["Comments"] ;

您还可以先将 的返回值存储sqlReader["Comments"]在变量中以缩短表达式

var comments = sqlReader["Comments"];
objStreamItem.Comments = comments is DBNull ? 0 : (Int32)comments;
于 2011-12-27T19:13:27.733 回答
2

??操作员检查,nullsqlReader["Comments"]永远不会null。它要么是Int32,要么是DBNull。您可以null转换为Int32?,但不能使用DBNull.Value。您可以sqlReader["Comments"] as Int32?改用,它检查结果是否可以转换为Int32,如果不能,则分配null

于 2011-12-27T18:56:22.373 回答
1

该语句尝试在合并值之前执行强制转换。您需要添加括号。从您上面的示例来看,该字段看起来也是 anint而不是 an int?

Comments = (Int32)(sqlReader["Comments"] ?? 0);
于 2011-12-27T18:45:58.627 回答