web-dev-qa-db-ja.com

Int64はC#のlongと等しくありませんか?

SqlCeConnection を介して、C#でSQLおよびデータベースをいじっています。私は ExecuteReader を使用して結果を読み取り、 BigInt Longsに読み取られるレコードIDの値を使用しています。

今日、COUNTベースのステートメント( 'SELECT COUNT(*)FROM X')を使用するSQLステートメントで遊んでおり、これらの単一値の結果を読み取るために ExecuteScalar を使用しています。

しかし、私は問題に遭遇しました。これまで使用してきたLongデータ型に値を格納することはできません。 Int64に保存できます。

レコードの最大数を取得するために、レコードIDにBigIntを使用しています。

したがって、BigInt 8バイトはInt64です。どちらも64ビット符号付き整数であるため、LongはInt64と等しくありませんか?

したがって、なぜInt64をLongにキャストできないのですか?

long recordCount =0;

recordCount = (long)selectCommand.ExecuteScalar();

エラーは次のとおりです。

指定されたキャストは無効です。

BigIntをLongに読み込むことができます。問題ありません。 SQL COUNTをlongに読み込めません。

COUNTはInt(Int32)を返すため、実際には問題はInt32をlongにキャストすることです。

28
user427165

longInt64in .NET ; C#の単なるエイリアスです。問題は戻り値をlongにキャストすることであり、クエリから返される型が確実にわからない限り、エラーが発生する理由はわかりません。 SQL BigIntはlongに変換可能でなければなりません。

戻ってくるのがCOUNT(*)の場合、Int32です。 Convert クラスを使用する必要があります。

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

カウントが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 

つまり、同じコードにコンパイルされるように見えます。