【C#】DataTable にLinqを使うと、めっちゃ便利!5選

当ページのリンクには広告が含まれています。

一覧形式のデータを保持するのに便利なDataTableクラスですが、これにLinqを使うと、ループでごちゃごちゃやっていた処理が、たった1行で済んでしまいます。

今回は、DataTableを扱う上で、知っておくと便利なLinqの使い方をご紹介します。

ちなみに、この記事ではカラムの事を列と表現しています。

目次

便利な使い方

これから紹介するサンプルソースは、 dt という名前のDataTableインスタンスが、既に出来上がっているという前提です。

任意の列を配列に変換して返す

全ての列を取り出す場合は、次の様に書きます。

dt.AsEnumerable().Select(抽出対象).ToArray()

dt.AsEnumerable() と書きましたが、これは dt.Rows.Cast<DataRow>().Select ~ のようにDataTableを DataRow にキャスト(型変換)する記述でもOKです。

任意の列に値を代入する

特定の列に値を代入する(置き換える)場合は、次の様に書きます。

dt.AsEnumerable().Select(代入式).ToArray()

ポイントは末尾のToArray() です。

これが無いと内部的に処理はしてくれるものの、DataTableへの反映(書き戻し)が行われませんのでご注意ください。

ちなみに、ToArray()の代わりに ToList() でもOKです。

DataTableの全ての列名を配列で返す

DataTableをDataColumnでキャストするとSelectの中で列名が参照できますので、これを利用します。

dt.Columns.Cast<DataColumn>().Select(DataColumnから取り出したいプロパティ).ToArray()

実際のサンプルは次の様になります。

ColumnNameの代わりにDataType を指定すると、全ての列のデータ型が取得できます。

DataTableの全ての列名を変更する

DataTableの列名を変更することも可能です。

dt.Columns.Cast<DataColumn>().Select(代入式).ToArray()

条件を満たす行だけ抜き出してDataTableを作成する

特定の条件の行を抜き出したい場合、Where を使いますが、最後に CopyToDataTable() を付けてあげることで、抽出した結果からDataTableを作成してくれます。

dt.AsEnumerable().Where(抽出条件).CopyToDataTable()

同様のことはDataViewクラスを使っても出来ますが、3行になってしまいます。

無理やり1行に書く事も出来ます。

処理速度は遅いですが、DataTableのSelect()メソッドでデータを抜き出して、CopyToDataTable()メソッドでDataTableにする方法もあります。

こちらはDataViewに比べて素直な書き方になります。

Linqの処理速度は高速ですが抽出条件の記述が煩雑になるので、場合によって使い分けが必要になります。

データ抽出の速度比較

LinqのWhere、DataViewのRowFilter、DataTableのSelectのそれぞれの方法について、簡単に速度を比較してみました。

ます小規模なDataTable(218行、12列)から、指定した条件で17行のデータを抽出した場合、LinkのWhereが最も速く、DataView.RowFilterが最も遅い結果となりました。

218行×12列のDataTbleから17行を抽出する場合(100回の平均時間)
Linq.Where
0.0590922 ms
DataTable.Select
0.1409331 ms
DataView.RowFilter
0.1990314 ms

次に、比較的大きなDataTalbe(10万行、12列) から、12444行のデータを抽出した場合も、LinkのWhereが最も速く、DataView.RowFilterが最も遅い結果となりました。

10万行×12列のDataTbleから12444行を抽出する場合(100回の平均時間)
Linq.Where
37.353736 ms
DataTable.Select
76.593718 ms
DataView.RowFilter
115.459477 ms

以上様の結果から、DataTableの規模に関係なく Linq が最も速く、2番目に DataTable のSelectメソッド、一番遅いのが DataViewのRowFilter という結果となりました。

LinkのWhereの処理速度は、DataViewのRowFilterに比べて、小さなDataTableでは3倍以上、比較的大きなDataTableで2倍以上も高速であるという結果になりました。

まとめ

いかがでしたでしょうか。

Linqを使うと今までforループで数行記述が必要だった抽出処理が1行で書けてしまいます。

また、指定条件によるデータ抽出では、Linqが他の方法に比べて2~3倍速いということも分かりました。

あまり複雑な記述はよけいに見難くなりますが、単純なものだと可読性も上がります。

Linqが使えるところは、どんどん使っていきましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次