【ASP.NET】C# DataTable.Select()メソッドにはやはりバグがある!?

久しぶりに技術的な記事でも。
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さん。気づいていたら早急に対応して頂きたいものです。
それとも何か理由があるのだろうか??
また分かり次第、記事にしてみようと思う。

「【ASP.NET】C# DataTable.Select()メソッドにはやはりバグがある!?」への5件のフィードバック

  1. 僕も試してみました。
    ほんとですね。
    SelectしてるDataRowの中身見てみても全然SelectされてないDataRowが返ってきてました。
    ただ・・・。
    やっぱりカラムの削除ってなかなかしないんで、問題になることは少なそうですねー。

  2. あっ。それと、
    「DataViewRowState.None」 ってところ 「DataViewRowState.CurrentRows」じゃないですか?
    「DataViewRowState.None」のままだと、ずっと0件が返ってきてました。

  3. ===YOHEIどの===
    お!ありがとう。
    試してくれたんだ。
    あなたが試してくれるとは心強い。笑
    DataViewRowState.CurrentRowsだね。。。
    間違えてた。笑。記事を修正しなくちゃ。
    確かに、カラムの削除ってしないけど。。。
    他にもMSDNの記事にもあるように

    「上記再現コードで “Column2” の AllowDBNull を true にすると、次のエラーが発生する。
    … エラー:インデックスが配列の境界外です。」

    等、DataTable.Select()メソッドにはまだまだ問題がありそうだよね。
    最近ホント慎重に使うようになったわ。笑

    ほんとはこんな技術的な記事のストックがまだあるんだけど。。。
    検証が不十分で公開出来ない分もあるのよ。。。

    暇な時にでもまた技術討論しましょう。
    まぁ一度うちに遊びにきてよ。
    聞きたいこともたくさんある。笑

コメントを残す

メールアドレスが公開されることはありません。

5 × one =