Isn't an Int64 equal to a long in C#?
我一直在通过sqlceConnection在C中使用SQL和数据库。我一直在使用ExecuteReader来读取结果和记录ID的bigint值,这些记录ID被读取到long中。
今天,我一直在使用基于计数的语句("select count(*)from x")的SQL语句,并一直在使用executescalar读取这些单值结果。
然而,我遇到了一个问题。我似乎无法将这些值存储到一个长数据类型中,我到目前为止一直在使用这种数据类型。我可以把它们存进Int64。
我一直在使用bigint作为记录ID来获取最大的潜在记录数。
因此,bigint 8字节是int64。long不等于int64吗,因为两者都是64位有符号整数?
所以,为什么我不能把一个int64转换成一个long?
1 2 3
| long recordCount =0;
recordCount = (long)selectCommand.ExecuteScalar(); |
错误是:
Specified cast is not valid.
我能把一个大字读成一个长字。这不是问题。我无法将SQL计数读取为长。
count返回一个int(int32),因此问题实际上是将int32强制转换为long。
- recordcount定义为什么?
- @BoltClock:您可以直接将int强制转换为long(实际上,您甚至不需要强制转换,因为有一个隐式转换可用)。OP的问题是你不能将盒装的int拆箱到long。装箱值类型(通常)需要取消装箱到完全相同的类型。
long是.NET中的Int64;它只是C中的别名。您的问题是将返回值强制转换为long,除非我们确定知道从您的查询返回的类型,否则我们不知道您为什么会收到错误。SQL bigint必须可转换为long。
如果是计数(*)返回,则为Int32。您需要使用Convert类:
1
| long l = Convert.ToInt64(selectCommand.ExecuteScalar()); |
- +1,你说得对,COUNT返回一个32位整数,当他们试图将int解绑到long时,我很确定这就是op问题的根源。虽然没有必要使用明确的Convert.ToInt64:由于int可以隐式地转让给long,因此long l = query.ExecuteScalar();将工作得很好。
- 是的,这是有道理的,我会尝试找到一个类似的问题,乔恩·斯基特几天前回答过。
- long l = query.ExecuteScalar()在编译时将失败,因为您无法将对象隐式转换为long。同样,long l = (long)query.ExecuteScalar()在运行时失败,因为此强制转换无效。使用Convert.ToInt64将对象转换为Int64或long。
- @另一种耸耸肩的说法是:哦,你说得对:long l = (int)query.ExecuteScalar();可以做到这一点(尽管我不确定它是否比使用Convert.ToInt64更易读)。
- @aliostad我可以将bigint存储到long no problem我不能将count结果存储为long i get"指定的强制转换无效。",但是,我可以将int64强制转换为long,它应该与long相同?
- @andicrook:COUNT的结果是一个int,而不是一个BIGINT,我敢打赌,你不能将它解绑到Int64或long上(因为它们是完全相同的类型)。如果您确信您可以,那么请向我们展示(1)确切的工作代码,(2)确切的损坏代码。
- @andicrook:要将它存储在一个long/Int64变量中,那么您需要像上面aliostad的答案那样执行long l = Convert.ToInt64(selectCommand.ExecuteScalar());,或者执行long l = (int)selectCommand.ExecuteScalar();。
- @lukeh your right count返回一个int(int32),因此问题实际上是将int32强制转换为long。
如果您认为计数将溢出int/int32,那么应该在SQL中使用count_big(),它具有正确的返回类型。
至于为什么演员不工作,我不确定。以下C:
1 2 3
| System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
long lCount = (long)cmd .ExecuteScalar();
Int64 iCount = (Int64 )cmd .ExecuteScalar(); |
编译到此IL:
1 2 3 4 5 6 7 8 9 10 11 12
| 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()也不会转换为长。计数和计数"大"会变成一个整数64,但不会变成一个长整数64,为什么?
- @andicrook-你能像我上面所做的那样,将你的代码解压到IL的长版本和Int64版本中,并将你的结果添加到问题中吗?
- 我的错误我没有重新编译仍然没有工作我认为计数太大是由SQL Compact版本支持的"该函数不被SQL Server Compact版本识别。[函数名=count_big,数据类型(如果已知)=]"
- @andicrook—COUNT()的返回类型是in t/int32,因此将其存储在in t/int64中并不能获得任何信息。没错,Compact不支持COUNT_BIG(),但我认为这是您第一次提到这是您的目标SQL服务器。
- @Damien ou the ou Unbeliever I did specify I was using compact edition I said via sqlceConnection(ce=compact edition)not sqlconnection.你说得对,我没有意识到计数的局限性,因此我无法从Int64或长时间中获得好处。还需要查找此版本的每个表的最大记录数,并可能将所有内容都放到Int32中。不过,稍后我将添加对完整的SQL Server的支持,因此很好地了解count-big。谢谢