Isn't an Int64 equal to a long in C#?

2019-01-19 10:02发布

I have been playing around with SQL and databases in C# via SqlCeConnection. I have been using ExecuteReader to read results and BigInt values for record IDs which are read into Longs.

Today I have been playing with SQL statements that use COUNT based statements ('SELECT COUNT(*) FROM X') and have been using ExecuteScalar to read these single valued results.

However, I ran into an issue. I can't seem to store the values into a Long data type, which I have been using up to now. I can store them into Int64's.

I have been using BigInt for record IDs to get the maximum potential number of records.

A BigInt 8 bytes therefore is an Int64. Isn't a Long equal to an Int64 as both are 64-bit signed integers?

Therefore, why can't I cast an Int64 into a Long?

long recordCount =0;

recordCount = (long)selectCommand.ExecuteScalar();

The error is:

Specified cast is not valid.

I can read a BigInt into a Long. It is not a problem. I can't read an SQL COUNT into a long.

COUNT returns an Int (Int32), so the problem is in fact casting an Int32 into a long.

2条回答
Luminary・发光体
2楼-- · 2019-01-19 10:13

long is Int64 in .NET; it is just an alias in C#. Your problem is casting the return value to long and unless we know the type coming back from your query for sure, we would not know why you get an error. SQL BigInt must be convertable to long.

If it is the COUNT(*) which is coming back, then it is Int32. You need to use the Convert class:

long l = Convert.ToInt64(selectCommand.ExecuteScalar());
查看更多
女痞
3楼-- · 2019-01-19 10:29

If you're thinking that your counts are going to overflow an int/Int32, you ought to use COUNT_BIG() in your SQL instead - it has the correct return type.


As to why the casts aren't working, I'm not sure. The following C#:

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

Compiles to this 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 

That is, they appear to compile to identical code.

查看更多
登录 后发表回答