C# SqlDataReader.GetInt64 System.InvalidCastException:指定的转换无效

问题描述 投票:0回答:1

我知道这个问题的通常答案,但它们似乎并不适用。

我们有一个流程,可以遍历来自众多供应商的数据并将其纳入一个一致的流中。我们最近添加了一家供应商,要求将我们的主键更改为 bigint。

一些字符串处理在 C# 中更容易完成,所以我更改了 C# 代码

primaryKey = reader.GetInt32(0);

primaryKey = reader.GetInt64(0);

认为系统中较旧的供应商会直接转换为 Int64。

我让每个人都启动并运行,我注意到一些但不是所有旧供应商的记录(int32 主键)都得到了处理。查看日志文件,我在 reader.GetInt64() 调用处理一些批次时看到 InvalidCastException

我知道通常的回答是“哦,你可能会得到空值”,但是

    它是主键。不能为空
  • 该代码已与 reader.GetInt32(0) 调用一起运行了十多年
  • 所有批次(成功和不成功)的所有数字都在1.81亿范围内
我更改了代码,以便在 IsDBNull() 返回 true 时抛出 ArgumentNullException,但这从未触发。

堆栈跟踪有

at System.Data.SqlClient.SqlBuffer.get_Int64()
但是如果没有源代码或行号,就很难走得更远。

我放了

CAST(keyID as bigint) keyID
在返回批次的存储过程中,问题已经消失。

不过还是很好奇。为什么在查询结果中给出 Int32 时 reader.GetInt64() 会偶尔抛出 InvalidCastException?

c# sqldatareader
1个回答
0
投票
当查询结果中给出 Int32 时,为什么 reader.GetInt64() 会偶尔抛出 InvalidCastException?

reader.GetInt64()

 应该抛出一个 InvalidCastException 异常,而不仅仅是“偶尔”,而是
每一次。根据文档

不进行任何转换;因此,检索到的数据必须已经是 64 位有符号整数。

换句话说,如果列值为 Int32,那么 GetInt64 将抛出 InvalidCastException。它不会为您将 Int32 转换为 Int64。所有其他 SqlDataReader.Get... 方法也是如此。

可能最好的解决方法是调整 SQL 查询以始终返回 Int64 值,就像您所做的那样。或者,要处理 Int32 和 Int64 值,您可以将列值读取为

object

,然后使用 
Convert.ToInt64(reader[0])
 执行转换。

© www.soinside.com 2019 - 2024. All rights reserved.