【问题标题】:Isn't an Int64 equal to a long in C#?Int64 不等于 C# 中的 long 吗?
【发布时间】:2011-07-12 17:33:29
【问题描述】:

我一直在通过SqlCeConnection 在 C# 中使用 SQL 和数据库。我一直在使用ExecuteReader 读取结果,并使用BigInt 读取读入 Long 的记录 ID 值。

今天我一直在使用基于 COUNT 的语句 ('SELECT COUNT(*) FROM X') 的 SQL 语句,并且一直在使用 ExecuteScalar 来读取这些单值结果。

但是,我遇到了一个问题。我似乎无法将值存储到我一直在使用的 Long 数据类型中。我可以将它们存储到 Int64 中。

我一直在使用 BigInt 作为记录 ID,以获得最大的潜在记录数。

因此,一个 BigInt 8 字节是一个 Int64。 Long 不等于 Int64,因为两者都是 64 位有符号整数吗?

因此,为什么我不能将 Int64 转换为 Long?

long recordCount =0;

recordCount = (long)selectCommand.ExecuteScalar();

错误是:

指定的转换无效。

我可以将 BigInt 读入 Long。这不成问题。 我无法将 SQL COUNT 读入 long。

COUNT 返回一个 Int (Int32),所以问题实际上是将 Int32 转换为 long。

【问题讨论】:

  • recordCount 定义为什么?
  • @BoltClock:您可以直接将int 转换为long(实际上您甚至不需要转换,因为有一个可用的隐式转换)。 OP 的问题是您无法将已装箱的int 拆箱为long。装箱的值类型(通常)需要拆箱为完全相同的类型。

标签: c# sql-server-ce long-integer int64 int32


【解决方案1】:

longInt64 in .NET;它只是 C# 中的别名。您的问题是将返回值转换为long,除非我们确定从您的查询返回的类型,否则我们不会知道您为什么会收到错误。 SQL BigInt 必须可转换为 long

如果返回的是 COUNT(*),那么它是 Int32。您需要使用Convert 类:

long l = Convert.ToInt64(selectCommand.ExecuteScalar());

【讨论】:

  • +1,你说得对,COUNT 返回一个 32 位整数,我很确定这是 OP 在尝试拆箱 int 时问题的根源到long。虽然不需要显式的Convert.ToInt64long l = query.ExecuteScalar(); 可以正常工作,因为int 可以隐式分配给long
  • 是的,这很有道理,我会尝试找到 Jon Skeet 几天前回答的类似问题。
  • long l = query.ExecuteScalar() 将在编译时失败,因为您无法将对象隐式转换为 long。同样,long l = (long)query.ExecuteScalar() 在运行时失败,因为此转换无效。使用 Convert.ToInt64 将对象转换为 Int64 或 long。
  • @anothershrubery:哎呀,你说得对:long l = (int)query.ExecuteScalar(); 可以解决问题(尽管我不确定它是否比使用 Convert.ToInt64 更具可读性)。
  • @Aliostad 我可以将 BigInt 存储为 long 没问题我无法将 COUNT 结果存储为 long 我得到 {"Specified cast is not valid."},但是,我可以转换为 int64哪个应该和long一样?
【解决方案2】:

如果您认为您的计数将溢出 int/Int32,您应该在 SQL 中使用 COUNT_BIG() 代替 - 它具有正确的返回类型。


至于演员表为什么不起作用,我不确定。以下 C#:

System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
long lCount = (long)cmd.ExecuteScalar();
Int64 iCount = (Int64)cmd.ExecuteScalar();

编译到这个 IL:

L_0000: nop 
L_0001: newobj instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor()
L_0006: stloc.0 
L_0007: ldloc.0 
L_0008: callvirt instance object [System.Data]System.Data.Common.DbCommand::ExecuteScalar()
L_000d: unbox.any int64
L_0012: stloc.1 
L_0013: ldloc.0 
L_0014: callvirt instance object [System.Data]System.Data.Common.DbCommand::ExecuteScalar()
L_0019: unbox.any int64
L_001e: stloc.2 
L_001f: ret 

也就是说,它们似乎编译成相同的代码。

【讨论】:

  • COUNT_BIG() 也不长。 COUNT 和 COUNT_BIG 将转换为 int64 但不会转换为 long 当 long 是 int64 为什么?
  • @andicrook - 您能否像我在上面所做的那样,将您的代码反编译为长版本和 Int64 版本的 IL,然后将您的结果添加到问题中?
  • 我的错误我没有重新编译仍然没有工作我不认为 SQL Compact Edition 支持 COUNT_BIG {"SQL Server Compact Edition 无法识别该函数。[ 函数名称 = COUNT_BIG,数据类型(如果已知)=]"}
  • @andicrook - COUNT() 的返回类型是 int/Int32,因此将其存储在 int/Int64 中不会为您带来任何好处。没错,compact 不支持COUNT_BIG(),但我认为这是您第一次提到这是您的目标 SQL Server。
  • @ Damien_The_Unbeliever 我确实指定我使用的是精简版,我说的是通过 SqlCeConnection(Ce = 精简版)而不是 SqlConnection。没错,我没有意识到 COUNT 的限制,因此无论如何我都无法从 int64 或 long 中获得好处。还需要查找此版本的每个表的最大记录数,并可能将所有内容都删除到 int32。但是,我稍后会添加对完整 SQL 服务器的支持,因此很高兴了解 COUNT_BIG。谢谢
猜你喜欢
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2017-05-25
  • 2016-08-20
  • 2013-09-22
  • 2018-04-19
相关资源
最近更新 更多