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にキャストすることです。
カウントが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
つまり、同じコードにコンパイルされるように見えます。