OITA: Oika's Information Technological Activities

@oika 情報技術的活動日誌。

DataRowとNullの微妙な関係

ADO.NETのDataAdapterとかを使おうとすると、DataSetやDataTable経由で
DataRowの値をいじる処理が絡むことが多いと思うが、
このクラスはNull値に関してちょっと直感的でない動きをする。

まずサンプルとして、以下のようなint列とstring列のDataTableを用意して
そこからDataRowを作っておく。

var dt = new DataTable();
dt.Columns.Add("FldInt",    typeof(int));
dt.Columns.Add("FldString", typeof(string));

var row = dt.NewRow();

このDataRowに対し、String列にNullを入れて、直後にそれがNullかどうかを確認する。

row["FldString"] = null;
bool isNull = row["FldString"] == null; //false

なんとこれが結果Falseになるのであります。
じゃあ中には何が入っているかというと、DBNullが入っているのだ。

row["FldString"] = null;
bool isNull = row["FldString"].Equals(DBNull.Value); //true

わかりにくいことに、このDBNull.ValueはToString()すると空の文字列を返すので、
知らないと、まるでNullが空文字に置換されるように見えてしまう。

これだけの話なら別に問題ないのだけど、
びっくりするのは、int型の列にNullを入れた場合

row["FldInt"] = null;

↑のコードはなんと、ArgumentExceptionを投げる。
Nullは入れられないから代わりにDBNullを入れてねと。
なんでだよー。どうせNull許容型でも勝手に変換するんじゃねぇかよー。

というわけで、まとめると以下のようになります。
・Null許容型の列にNullを入れるとDBNullに変換される
・Null非許容型の列にはNullを入れようとするとエラーになる

以上。