echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

DataTableからListにデータを変換する方法

やりたいこと

  • DataTableの内容(主にデータベースのデータ)に対しても、ListみたいにLinqで扱いたい。

理由

  • ループで1行ずつList.Add()すれば出来るけど、Enumerable.ToList()みたいに スマートに実現出来ないか? (コードもシンプルになるし)
  • 何だかんだ言っても、.net製の業務システムではまだまだDataTable(DataSet)が 現役なので、 変換ができるようになっておくと便利。
  • DataTableとListでは、後者の方が処理が早いみたいなので。(※)

※参照:意外と遅い DataTable 、なので List を使うと 5 倍早くなる

いきなり結論

「AsEnumerable()」メソッドを使えばOK。(.net Framework3.5以降)
このメソッドを実施するとIEnumerableオブジェクトが戻り値として返されるので、 あとはToList()を実行すれば、Listに変換できる。

サンプルソース

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#について調べましたよ...ってことで。