2011-02-07 5 views
5

sqliteデータベーステーブルから選択したSystem.Data.SQLiteを使用しています列に「整数」型があり、次のような場合は'int'型のsqliteカラムから選択すると、.net intにキャストできますが、 'integer'カラムから選択できない場合

int x = (int)reader["myColumn"]; 

が失敗します。問題は値がnullではないことです。列はNULL可能ではありません。列のデータ型を 'int'に変更すると、正常に動作します。列の値は '2'、 '3'、 '4'などです。非常に大きなものはありません。

これが予期される動作であれば、誰でも知っていますか?

答えて

10

SQLiteの整数は、1,2,3,4,6,8バイトのいずれかに格納されています。ただし、オーバーフローまたは範囲外の例外は発生しません。

この場合、(int)は変換ではなくキャストです。 reader[]がinteger型のオブジェクトを返さなかった場合、それが異なる数値型を返している場合は、それに含まれる値にかかわらず、キャスト例外が発生します。

SQLite整数の有効な値の範囲に基づいて、値が64ビット整数のlongとして返されていると思います。確認するには、これを試してみてください。

object x = reader["myColumn"]; 
Debug.WriteLine(x.GetType().Name); 
+1

私は本当に長いx =(長い)読者["myColumn"];がうまく動作していることを発見した後、この質問に自分自身で答えることに戻っていました。あなたは絶対に正しい - それはInt64だった - だからちょうど長い変数を使用すると私のために働くだろう。 INTとINTEGERの動作が異なる理由については、それはまだ私にとって奇妙です。 INT/INTEGERからのキャストの成功/失敗をテーブル内の同じデータ値に対して繰り返すことができ、別のテーブルでも問題を再現できます。おそらく、ドライバーのわずかな矛盾。 – Rory

2

datareader.Item[]objectを返すため、例外が発生します。

問題は、ボクシング/アンボクシングによるものです。これは、データベース自体とは何の関係もないのです...

long a = 1; 
int b = 2; 
object objectA = a; 
object objectB = b; 
Console.WriteLine((int)a); 
Console.WriteLine((long)b); 
Console.WriteLine((int)objectA); 
Console.WriteLine((long)objectB); 

コンソール出力2、その後1、しかしobjectAobjectBのキャストに例外がスローされます。これは.NETの特徴であり、ODBCドライバとは関係ありません。

関連する問題