8

我有一个包含空值的表,我需要使用 SqlDataReader 从表中获取数据。我不知道如何安全地将 DBNull 转换为 int。

我现在正在这样做:

...
reader = command.ExecuteReader();
while (reader.Read()) {
     int y = (reader["PublicationYear"] != null) ? Convert.ToInt32(reader["PublicationYear"]) : 0;
     ...
}
...

但是Object cannot be cast from DBNull to other types.当 PublicationYear 为空时得到一个。

我怎样才能安全地获得价值?

谢谢。

4

9 回答 9

13

你应该比较reader["PublicationYear"]DBNull.Value而不是null

于 2012-02-21T12:37:21.683 回答
4

DBNull不一样null。你应该尝试这样的事情:

int y = (reader["PublicationYear"] != DBNull.Value) ? ...
于 2012-02-21T12:37:40.167 回答
3
int ord = reader.GetOrdinal("PublicationYear");
int y = reader.IsDBNull(ord) ? 0 : reader.GetInt32(ord);

或者,或者:

object obj = reader["PublicationYear"];
int y = Convert.IsDBNull(obj) ? 0 : (int)obj;
于 2012-02-21T12:37:56.547 回答
2

改变

reader["PublicationYear"] != null

reader["PublicationYear"] != DBNull.Value

于 2012-02-21T12:38:22.710 回答
2

您应该明确检查返回的值是否属于类型DBNull

while (reader.Read()) {
     int y = (!reader["PublicationYear"] is DBNull) ? Convert.ToInt32(reader["PublicationYear"]) : 0;
     ...
}

实际上,您可以按值和类型进行比较:

reader["PublicationYear"] != DBNull.Value

简而言之-您可以期望DBNull从数据库中返回空值,而不是空值本身。

于 2012-02-21T12:38:24.657 回答
2

作为替代方案,您可以执行以下操作。当您将 DBNull 转换为 0 时,请更改执行选择的过程。以便选择本身为空值返回零。

片段来展示这个想法

    SELECT ...
           ,ISNULL (PublicationYear, 0) as PublicationYear
           ...
    FROM sometable

这样做的好处是,您的代码中不需要额外的检查。

于 2012-02-21T12:48:41.453 回答
1

这就是错误:(reader["PublicationYear"] != null) 您应该测试 DBNull.Value....

于 2012-02-21T12:37:54.723 回答
1

将您的测试从 更改(reader["PublicationYear"] != null)(reader["PublicationYear"] != DBNull.Value).

于 2012-02-21T12:37:58.763 回答
1

数据库空值应与DBNull.Value

reader = command.ExecuteReader();

while (reader.Read()) 
{
     int y = (reader["PublicationYear"] != DBNull.Value) ? Convert.ToInt32(reader["PublicationYear"]) : 0;
     ...
}
于 2012-02-21T12:48:12.227 回答