Generic ListとDataTableを相互変換するC#コード

C#でGeneric List型でデータを取得してきたもののDataTable型にして使いたい場合がたまにある。そのときに相互に変換するメソッドを組んでおくと楽だ。


LINQが使えるようになってからGeneric List型を多用するコードを多く書くようになってきた。LINQでデータベースなどから値を取得するクエリーを記述し、ToListメソッド一発でデータを取得してList型にしてくれる。なんて便利な世の中になったことだろう。

だが、古いコードを保守しているとDataTable型でデータを渡したいことが多い。だからといってデータのクラスごとに変換コードをいちいち書くのも面倒である。そんなときにList型とDataTable型の変換メソッドを用意しておくと便利だ。リフレクションを使うと簡単に実現できる。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Collections;

namespace ListToDataTableTest
{
    class Item
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public double Value { get; set; }
        public DateTime UpdateDateTime { get; set; }
    }

    class Program
    {
        private static DataTable ConvertToDataTable<T>(T list) where T : IList
        {
            var table = new DataTable(typeof(T).GetGenericArguments()[0].Name);
            typeof(T).GetGenericArguments()[0].GetProperties().
                ToList().ForEach(p => table.Columns.Add(p.Name, p.PropertyType));
            foreach (var item in list)
            {
                var row = table.NewRow();
                item.GetType().GetProperties().
                    ToList().ForEach(p => row[p.Name] = p.GetValue(item, null));
                table.Rows.Add(row);
            }

            return table;
        }

        private static T ConvertToList<T>(DataTable table) where T : IList, new()
        {
            var list = new T();
            foreach (DataRow row in table.Rows)
            {
                var item = Activator.CreateInstance(typeof(T).GetGenericArguments()[0]);
                list.GetType().GetGenericArguments()[0].GetProperties().ToList().
                    ForEach(p => p.SetValue(item, row[p.Name], null));
                list.Add(item);
            }

            return list;
        }

        static void Main(string[] args)
        {
            // テストデータを用意
            var list = new List<Item>();
            for (int i = 0; i < 20; i++)
            {
                list.Add(new Item() { ID = i, Name = "Name of " + i.ToString(),
                    Value = i, UpdateDateTime = DateTime.Now });
            }

            // ListをDataTableへ
            var resultTable = ConvertToDataTable<List<Item>>(list);

            // DataTableをListへ
            var resultList = ConvertToList<List<Item>>(resultTable);
        }
    }
}

Follow me!

Feedlyで新着記事をチェックしよう!

Feedlyでフォローしておけば、新着記事をチェックすることができます。ぜひ、この機会にFeedlyに追加しておきましょう。