none
DB テーブルのデータが持つ変数の型について教えてください。 RRS feed

  • 質問

  • みなさま、お世話になります。

    DBからデータを読み込みコーディングしていますが、テーブルを入れ替えてから、
    以下のようなコードを書くと

        int x;

        var query = from ele in dataContext.テーブル
                        where ele.要素1 == Code
                        select ele;

        x = query.First().要素2;

    『型 'int?' を'int'に暗黙的に変換できません。明示的な変換が存在します。
    (castが不足していないかどうかを確認してください)』

    とエラーが出るようになりました。
    当然 (int)とキャストするとエラーはなくなります。

    以前、使っていたテーブルでは、キャストは必要ありませんでした。
    テーブルの定義を開き、そのカラムの型を確認すると間違いなく【int】になっています。
    新旧テーブルの定義で違いを確認するのですが、その違いが見つかりません。

    int x の【int】では、struct System.Int32 と示されていますし、SQL SetverDBの
    テーブルでのデータ型【int】は4バイトの長整数型だったと認識しており、双方の型は
    一致していると思っています。
     
    そもそも、テーブルの定義で両者を比べてみても違いがあるように見えないのに、
    同じようにコーディングできないのが何故なのか分かりません。
    まぁ、(int)とキャストすれば特に問題は無いようなのですが、私の理解していない
    所に何か違いがあるのではと思い、その違いを知りたくて質問をさせて頂きました。

    どうぞ、よろしくお願いいたします。

    2010年4月23日 15:31

回答

  • DB 側が INT NOT NULL から INT NULL に変更されたのでは?

    INT NOT NULL では、First() で1行目を取り出した場合、取り出しに成功していれば必ず int (System.Int32) が返されますが、INT NULL では、取り出した結果が NULL の場合があるため、int? (System.Nullable<System.Int32>) が戻値になります。

    蛇足ですが、クライテリアの条件がプライマリキーやユニークキー等の1行だけのデータを検索するものの場合、First() ではなく Single() を利用できます。また、DB の検索結果が0件の場合がある場合、FirstOrDefault() や SingleOrDefault()、EmptyIfDefault() 等を利用しないと例外が発生します。

    また、int? は int と異なり null を保持できるので、いきなり (int) とキャストすると DB 側が NULL の場合には例外となります。

    int? x = ...;
    if (x.HasValue) { ...x に値が格納されていれば...}
    if (x != null) { ...x に値が格納されていれば... }

    など、値が確認されていることをチェックしたり、null の場合に -1 として扱う等のルールが決まっている場所であれば、

    int n = x ?? -1; // x が null の場合 -1 とする

    などできます。またキャストしなくても、

    int n = x.Value;

    と、Value プロパティを使用して値を取得できます。

    2010年4月23日 23:45

すべての返信

  • DB 側が INT NOT NULL から INT NULL に変更されたのでは?

    INT NOT NULL では、First() で1行目を取り出した場合、取り出しに成功していれば必ず int (System.Int32) が返されますが、INT NULL では、取り出した結果が NULL の場合があるため、int? (System.Nullable<System.Int32>) が戻値になります。

    蛇足ですが、クライテリアの条件がプライマリキーやユニークキー等の1行だけのデータを検索するものの場合、First() ではなく Single() を利用できます。また、DB の検索結果が0件の場合がある場合、FirstOrDefault() や SingleOrDefault()、EmptyIfDefault() 等を利用しないと例外が発生します。

    また、int? は int と異なり null を保持できるので、いきなり (int) とキャストすると DB 側が NULL の場合には例外となります。

    int? x = ...;
    if (x.HasValue) { ...x に値が格納されていれば...}
    if (x != null) { ...x に値が格納されていれば... }

    など、値が確認されていることをチェックしたり、null の場合に -1 として扱う等のルールが決まっている場所であれば、

    int n = x ?? -1; // x が null の場合 -1 とする

    などできます。またキャストしなくても、

    int n = x.Value;

    と、Value プロパティを使用して値を取得できます。

    2010年4月23日 23:45
  • K. Takaoka さん、早速お返事頂き、ありがとうございました。

    ご指摘くださった通り、「Nullを許容」の項に違いがありました。
    この違いを修正する事でキャストは必要なくなりました。

    また、これまで理解していなかった【int?】の意味も、分かりました。
    その他、関連の知識もご教授頂き、感謝しています。

    どうも、有難うございました。
    今後とも、よろしくお願いいたします。

    この項は、これでクローズさせて頂きます。

    2010年4月24日 4:33