【问题标题】:Why converting int from SqlDataReader to long results in InvalidCastException?为什么将 int 从 SqlDataReader 转换为 long 会导致 InvalidCastException?
【发布时间】:2013-12-05 17:17:53
【问题描述】:

我在以下行得到一个无效的转换异常:

DestMinSeq = (long)rdr["MinSeq"];

当我将查询更改为将 MinSeq 转换为 BIGINT 而不是 INT 时,它可以工作。

问题:为什么将空头转为多头是违法的?

环境:

VS 2012 SSIS project script task. 
ADO.NET connection manager. 
SQL Server 2012.

【问题讨论】:

    标签: c# c#-4.0 ssis ssis-2012


    【解决方案1】:

    问题:为什么将空头转为多头是违法的?

    您正在尝试将 boxed 短片转换为长片。你可以在没有数据库的情况下看到这个:

    int x = 10;
    object o = x;
    long y = (long) o; // Bang!
    

    如果你在拆箱的时候转换成正确的类型,然后转换成你真正想要的类型,就可以了:

    DestMinSeq = (long)(int)rdr["MinSeq]";
    

    (我怀疑你想要int而不是short,但你必须检查一下。)

    【讨论】:

    • 我真的需要很长。查询结果可以来自 2 个数据库版本,其中一个列是 INT,另一个是 BIGINT。为了安全起见,我在查询中进行了 CAST,所以它应该总是返回一个有符号的 64 位值。
    • @Metaphor:是的,在这种情况下,您确实应该将演员表放入查询中。但希望这已经解释了为什么它以前不起作用。
    • 原来如此。我从读者那里得到盒装标量。我应该知道的。谢谢!
    • 那个解决方案实际上可能是最好的。
    【解决方案2】:

    问题是rdr["MinSeq"] 的类型是object(实际上是一个int 被装箱为一个对象)。当您尝试将object 转换为long 时,它会给您一个无效的转换,因为编译器不能简单地将object 类型的对象cast 转换为实际装箱类型以外的其他对象(在这种情况下int)。

    你可以试试这个,

     DestMinSeq = Convert.ToInt64(rdr["MinSeq"]);
    

    或者@Jon Skeet 建议的,实际上看起来更漂亮,

     DestMinSeq = (long)(int)rdr["MinSeq"];
    

    【讨论】:

    • 当查询返回一个 bigint 时,第二个版本将失败,它确实如此。
    • 当然,出于同样的原因,当代码返回 INT 时它会失败。第一个解决方案应该处理这两种情况以及更多情况,例如当标量是 string(表示数字的字符串)时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 2016-12-20
    相关资源
    最近更新 更多