やりたいこと
- DataTableの内容(主にデータベースのデータ)に対しても、ListみたいにLinqで扱いたい。
理由
- ループで1行ずつList.Add()すれば出来るけど、Enumerable
.ToList()みたいに スマートに実現出来ないか? (コードもシンプルになるし) - 何だかんだ言っても、.net製の業務システムではまだまだDataTable(DataSet)が 現役なので、 変換ができるようになっておくと便利。
- DataTableとListでは、後者の方が処理が早いみたいなので。(※)
※参照:意外と遅い DataTable 、なので List を使うと 5 倍早くなる
いきなり結論
「AsEnumerable()」メソッドを使えばOK。(.net Framework3.5以降)
このメソッドを実施するとIEnumerable
サンプルソース
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ConvDs2ListCs { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { // 今回はDataTable,DataRowCollectionは自前で用意。 var dt = new DataTable(); dt.Columns.Add("ORDER_NO"); dt.Columns.Add("USER_NO"); dt.Columns.Add("COUNTRY_CODE"); dt.Columns.Add("PREF_CODE"); var dr = dt.NewRow(); dr["ORDER_NO"] = "0001"; dr["USER_NO"] = "AAAA"; dr["COUNTRY_CODE"] = "JPN"; dr["PREF_CODE"] = "AIC"; dt.Rows.Add(dr); var dr2 = dt.NewRow(); dr2["ORDER_NO"] = "0002"; dr2["USER_NO"] = "BBBB"; dr2["COUNTRY_CODE"] = "USA"; dr2["PREF_CODE"] = "LA"; dt.Rows.Add(dr2); var dr3 = dt.NewRow(); dr3["ORDER_NO"] = "1003"; dr3["USER_NO"] = "CCCC"; dr3["COUNTRY_CODE"] = "UK"; dr3["PREF_CODE"] = "RD"; dt.Rows.Add(dr3); var dr4 = dt.NewRow(); dr4["ORDER_NO"] = "1004"; dr4["USER_NO"] = "DDDD"; dr4["COUNTRY_CODE"] = "FR"; dr4["PREF_CODE"] = "Z"; dt.Rows.Add(dr4); // ここから、DataTable→List<DataRow>への変換処理。 // 単にList<DataRow>に変換する場合、ToList<DataRow>()を使用する。 var list1 = dt.AsEnumerable().ToList<DataRow>(); // AsEnumerable()を実行すれば、Listに変換する前に // Linqを使用することももちろん可能。 // Where()でフィルタをかけたり... var list2 = dt.AsEnumerable() .Where(x => x["ORDER_NO"].ToString().Substring(0, 1) == "1") .ToList<DataRow>(); // DataTableの各行のデータを編集して、Listにする事も可能。 Func<DataRow, string> getRight = x => (x["PREF_CODE"].ToString().PadRight(2).Length <= 2) ? x["PREF_CODE"].ToString().PadRight(2) : x["PREF_CODE"] .ToString().Substring(1 ,2); var list3 = dt.AsEnumerable() .Select(x => x["ORDER_NO"].ToString() + x["COUNTRY_CODE"].ToString().PadRight(3) + getRight(x)).ToList<String>(); } } }
今回は少し短めですが、ちょっとC#について調べましたよ...ってことで。