2012-03-16 5 views
12

Microsoft AccessデータベースのデータをMS SQL Serverデータベースにアーカイブするコードがあります。 Accessテーブルから既にデータリーダーが読み込まれていて、挿入の準備としてSqlCommandにパラメータを追加しようとしている場合、型キャストが失敗しています。なぜshortからintへのキャストが失敗するのですか?

oSqlServerDbCmd_ForInsert.Parameters.AddWithValue("@Duration", 
    (int) oReader["Duration"]); 

oReaderからのフィールドは、実際にはAccess Integerであり、これはC#の略です。ここに短いものを投げると問題はありません。しかし、intにキャストすると、コードはInvalidCastExceptionをスローします。 MSDN documentation

"shortからint、long、float、double、またはdecimalへの暗黙の変換があらかじめ定義されています。"

...しかし、これはうまくいくはずです(明示的な型変換はなぜ暗黙の変換が定義されているのでしょうか?)。 AddWithValueはオブジェクトを受け入れるので、キャストは必要ではないことに気づきます。実際にコードからキャストを削除しましたが、このキャストが失敗した理由を説明したいと思います未来。

+1

このhttp://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

+0

のエリックリペットから良い記事これは、あなたの答えではありませんあなたの '@ Duration'パラメータには、数値データ型の場合、 'AddWithValue'呼び出しで文字列値を使用したくない場合です。 – phoog

+0

@phoogこの問題が本当に終わったことから気を散らしているので、私は変換を取り除くためにコードを編集しました。簡単な答えは、文字列の変換は、コードを継承したときにコード内にあることです。ソースDBのデータ型を変更するまでは動作していたので、コードを調べる必要はありませんでした。一度それが壊れて、私たちが掘り出したのは、文字列の変換が不要であることが分かりました(問題ではありませんが、それを信じるかどうかは分かりません)。 –

答えて

18

あなたが手に持つものは、unboxingのインスタンスです。ボックス化を解除するときは、元々boxedされていた値の型にunboxするだけです。そのタイプがAで、Bにアンボックスしている場合、はAからBへの暗黙の変換が存在するかどうかは関係ありません。(まだアンボックスは失敗します)。

Eric Lippertのclassic blog postを参照してください。

short myShort = 42; 
object o = myShort; 
int myInt = (int)o; //fails 

それはあなたが短い最初に戻ってキャストした場合、その後、intに成功します: - あなたがアンボクシングされているので、非常に特定の型にキャストする必要が

+0

+1私はいつもそのことを忘れています。 'オブジェクトo =(短い)10; int i =(int)o; 'が失敗します。 –

+1

ああ、意味があります。だから私は最初にそれを短いものとしてキャストしたのですが、問題なしでintとしてキャストできましたか? –

+1

@ awilson53:まったく。 – Jon

5

問題はoReader["Duration"]objectインスタンスを返すということです。

(int) (short) oReader["Duration"] 
+0

フィードバックをいただきありがとうございます、+1 ...私はあなたの両方が私の質問に答えたので、最初のムーバーと一緒に行かなければなりません。 –

関連する問題