2

型がNULL内部のデータベースから返された値を設定しようとすると、無効なキャスト例外が発生するのはなぜですか。CommentsInt32

私はこれを置き換えようとしています:

                try
                {
                    objStreamItem.Comments = (Int32)sqlReader["Comments"];
                    if (objStreamItem.Comments > 0) { 
                        listComments = Comment.GetAll(objStreamItem.Id);

                    }
                }
                catch (InvalidCastException)
                {
                    // Execute if "Comments" returns NULL
                    listComments = null;
                    objStreamItem.Comments = 0;
                }

これとともに:

Comments = ((Int32?)sqlReader["Comments"]) ?? 0

2つは異なるコンテキストにありますが、アイデアを得る必要があります。try catchブロックを使用する代わりに、よりエレガントな方法でこれを解決しようとしています。

ありがとう。

アップデート

これは、null許容整数としてデータベースに格納されます。

    public int? Comments
    {
        get;
        set;
    }

この質問に答えたり投稿したりしてくれたすべての人に感謝したいと思います。すべてが非常に有益でした。ありがとう!

4

4 に答える 4

7

DBNull値がnullの場合、SQLリーダーが返されます。DBNullからへの変換はなく、null合体演算子は合体する必要があるものとしてint?認識しません。DBNull.Value

編集3

(元のコードに関する別の問題:「コメント」がnull以外の場合、「コメント」はnullを返したと見なされますが、がGetAll()スローされInvalidCastExceptionます。)

hvdが指摘しているように、null許容型でas演算子を使用できます。

objStreamItem.Comments = sqlReader["Comments"] as int?;
listComments = (objStreamItem.Comments ?? 0) > 0 ? Comment.GetAll(objStreamItem.ID) : null;

Comment.GetAll()ただし、渡したIDにコメントがない場合に空のリストまたはヌル参照を返すように定義しただけであれば、これらすべてから身を守ることができます。

于 2011-12-27T18:55:30.370 に答える
2

オペレーターは??をチェックしますがnullsqlReader["Comments"]決してそうなることはありませんnullInt32、、またはのいずれかになりますDBNull。にキャストすることはできますが、でキャストnullするInt32?ことはできませんDBNull.ValuesqlReader["Comments"] as Int32?代わりに、結果をに変換できるかどうかをチェックし、変換できInt32ない場合はを割り当てるを使用できますnull

于 2011-12-27T18:56:22.373 に答える
2

三元表現がここへ行く道だと思います

objStreamItem.Comments = sqlReader["Comments"] is DBNull ? 0 : (Int32)sqlReader["Comments"] ;

の戻り値をsqlReader["Comments"]最初に変数に格納して、式を短縮することもできます。

var comments = sqlReader["Comments"];
objStreamItem.Comments = comments is DBNull ? 0 : (Int32)comments;
于 2011-12-27T19:13:27.733 に答える
1

そのステートメントは、値を合体させる前にキャストを実行しようとします。かっこを追加する必要があります。上記の例から判断すると、フィールドは:intではなくであるようにも見えます。int?

Comments = (Int32)(sqlReader["Comments"] ?? 0);
于 2011-12-27T18:45:58.627 に答える