以前、DataRowとNullの微妙な関係というのを書いたけど、
相変わらず、型なしDataSetの値の扱いは気難しいという話。
まずは、int型のカラムを一つだけ持つDataTableを用意して、
それ用の新規DataRowを作って、適当な値を入れる。
var dt = new DataTable(); dt.Columns.Add("FldInt", typeof(int)); var row = dt.NewRow(); row["FldInt"] = 1234;
こうすると、中に入ってるのはint値なので、
以下のようにして取り出せる。ここまでは良い。
var val = (int)row["FldInt"];
だけど、これを以下のようにshortやlongにキャストしようとすると
失敗するのである。
//throws InvalidCastException var sVal = (short)row["FldInt"]; //throws InvalidCastException var lVal = (long)row["FldInt"];
もちろん、一度intにキャストして取得した値から
shortやlongにキャストするのは何の問題もない。
結局、IEnumerable.Castメソッドでint→longはできないという話と同じで、
DataRowに入る時点でボックス化されていて、ボックス化解除変換になるから
失敗するんだな。
DataAdapterでDBからDataTableにがばっと値をとってきたときに
もとのカラム型がINTEGERだろうがSMALLINTだろうが
とりあえずintにしてしまえっていう横着なことを自分はよくやるので、
上記のようにキャストでとるのはちょっとこわくて、
以下のように文字列にしてからParseしておくことも多い。
パフォーマンスはいくらか悪いんだろうけど…。
var val = int.Parse(row["FldInt"].ToString());