久しぶりに技術的な記事でも。
MSDNのフォーラムで非常に興味深い投稿があったので自分でも色々試してみた。
僕自身もDataTable.Select()メソッドはなんか変だなぁと違和感をずっと感じていた。
前もブログの記事にしたけど、
やっぱりDataTable.Select()メソッドには何かしらのバグがあるとしか思えない。
まず下のソースコードだが、フォーラムの投稿を僕の普段の環境Visual Studio 2005、.NET Framework 2.0という条件に書き直して実行してみた。
DataTable dt = new DataTable();
dt.Columns.Add("Column1", typeof(string)).AllowDBNull = false;
dt.Columns.Add("Column2", typeof(string)).AllowDBNull = false;
dt.Columns.Add("Column3", typeof(string)).AllowDBNull = false;
// DataTable.Load などでは内部的に実行される
dt.BeginLoadData();
dt.EndLoadData();
// (回避その1 → 削除しない)
dt.Columns.Remove("Column1");
// (回避その2 → テーブルを作り直す)
//dt = dt.Copy();
Random r = new Random();
for (int i = 0; i < 1000; i++)
{
DataRow row = dt.NewRow();
row["Column2"] = "";
row["Column3"] = new string((char)r.Next('A', 'Z' + 1), 1);
dt.Rows.Add(row);
}
// DataView による絞り込み
DataView dv = new DataView(dt,"Column3 = 'C'",string.Empty,DataViewRowState.CurrentRows);
int rowCount1 = dv.Count;
// Select による絞り込み
int rowCount2 = dt.Select("Column3 = 'C'").Length;
// (回避その3 → 条件内で関数を使う)
int rowCount3 = dt.Select("convert(Column3, 'System.String') = 'C'").Length;
MessageBox.Show(
string.Format(
"1. DataView.RowFilter → {0}\r\n" +
"2. DataTable.Select → {1}\r\n" +
"3. DataTable.Select(2) → {2}",
rowCount1, rowCount2, rowCount3));
MSDNの投稿にもあるように、DataTableからカラムを削除すると、DataViewにキャストしたときの件数、DataTable.Select()で取得した件数、DataTable.Select()メソッド内で関数を使った場合の件数それぞれが一致しなかった。
やはり、DataTable.Select()メソッドにはバグがあるように思えてしかたない。
普段、よく使うメソッドだけに、慎重に使用しないといけないと思い直した。
Microsoftさん。気づいていたら早急に対応して頂きたいものです。
それとも何か理由があるのだろうか??
また分かり次第、記事にしてみようと思う。

僕も試してみました。
ほんとですね。
SelectしてるDataRowの中身見てみても全然SelectされてないDataRowが返ってきてました。
ただ・・・。
やっぱりカラムの削除ってなかなかしないんで、問題になることは少なそうですねー。
あっ。それと、
「DataViewRowState.None」 ってところ 「DataViewRowState.CurrentRows」じゃないですか?
「DataViewRowState.None」のままだと、ずっと0件が返ってきてました。
===YOHEIどの===
お!ありがとう。
試してくれたんだ。
あなたが試してくれるとは心強い。笑
DataViewRowState.CurrentRowsだね。。。
間違えてた。笑。記事を修正しなくちゃ。
確かに、カラムの削除ってしないけど。。。
他にもMSDNの記事にもあるように
「上記再現コードで “Column2” の AllowDBNull を true にすると、次のエラーが発生する。
… エラー:インデックスが配列の境界外です。」
等、DataTable.Select()メソッドにはまだまだ問題がありそうだよね。
最近ホント慎重に使うようになったわ。笑
ほんとはこんな技術的な記事のストックがまだあるんだけど。。。
検証が不十分で公開出来ない分もあるのよ。。。
暇な時にでもまた技術討論しましょう。
まぁ一度うちに遊びにきてよ。
聞きたいこともたくさんある。笑
ストック分、早く読みたいです。
また遊び行きますねー!!!
===YOHEIどの===
楽しみに待っております。笑