今回は、結果をDataTableで受け取る方法についてです。
前回までのやり方は、結果を配列として受け取っていました。
これはこれでいいのですが、場合によってはDataTableで取得できた方が
便利な場合もあります。
FileHelpersでは、FileHelperEngineクラスにて以下のメソッドが定義されています。
- ReadFileAsDT
- ファイルを指定してDataTableを取得
- ReadStreamAsDT
- Streamを指定してDataTableを取得
- ReadStringsAsDT
- 文字列を指定してDataTableを取得
なお、XXXXAsDTのAsDTを除いたメソッド名もあります。
こちらは、配列で結果を受け取る版のメソッドです。
てことで、以下サンプルです。
利用するファイルは、第一回目で利用したPersons.csvを利用しています。
using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using FileHelpers; using Gsf.Lib.Utils; namespace FileHelpersSamples3 { class Program { const string DATA_FILE = @".\Persons.csv"; public void Execute() { // // エンジンを構築. // FileHelperEngineengine = new FileHelperEngine (Encoding.GetEncoding("sjis")); // // データ読み取り. (配列版) // Person persons = engine.ReadFile(DATA_FILE); persons.ToList().ForEach(Console.WriteLine); // // データ読み取り.(DataTable版) // DataTable table = engine.ReadFileAsDT(DATA_FILE); // // データ読み取り.(DataTable版-2) // DataTable table2 = null; using (TextReader reader = new StreamReader(DATA_FILE, Encoding.GetEncoding("sjis"))) { table2 = engine.ReadStreamAsDT(reader); } // // データ読み取り.(DataTable版-3) // DataTable table3 = engine.ReadStringAsDT(File.ReadAllText(DATA_FILE, Encoding.GetEncoding("sjis"))); // // データ表示. // new { table, table2, table3 }.ToList().ForEach {0}", table.AsEnumerable().SequenceEqual(table2.AsEnumerable(), DataRowComparer.Default">*1; Console.WriteLine("table2 == table3 ?? => {0}", table2.AsEnumerable().SequenceEqual(table3.AsEnumerable(), DataRowComparer .Default)); } static void Main(string[] args) { (new Program()).Execute(); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } [DelimitedRecord(",")] public class Person { public int Id; public string Name; [FieldNullValue(-1)] public int Age; public string Tel; [FieldConverter(ConverterKind.Date, "yyyy/MM/dd hh:mm:ss")] public DateTime Birthday; public override int GetHashCode() { return this.ToString().GetHashCode(); } public override bool Equals(object obj) { if (base.Equals(obj)) { return true; } return (this.ToString() == ( (Person) obj).ToString()); } public override string ToString() { return string.Format("Id={0},Name={1},Age={2},Tel={3},BirthDay={4}", Id, Name, Age, Tel, Birthday); } } } #region My-Library namespace Gsf.Lib.Utils { public static class DataTableExtensions { public static void Dump(this DataTable table) { ObjectDumper.Instance.Dump(table); } } public class ObjectDumper { #region Fields protected Dictionary > _specializedFuncMappings; protected Dictionary > _genericFuncMappings; private static ObjectDumper _self = new ObjectDumper(); #endregion #region Constructor private ObjectDumper() { InitializeSpecializedFuncMappings(); InitializeGenericFuncMappings(); } #endregion #region Public Methods public static ObjectDumper Instance { get { return _self; } } public virtual void Dump(object o) { Dump(o, Console.Out); } public virtual void Dump(object o, TextWriter writer) { writer.WriteLine(ToString(o)); } public virtual string ToString(object o) { string result = string.Empty; if (o == null) { return result; } return GetValue(o); } #endregion #region Protected Methods protected virtual void InitializeSpecializedFuncMappings() { if (_specializedFuncMappings == null) { _specializedFuncMappings = new Dictionary >(); } _specializedFuncMappings[typeof(Control)] = (o) => { string result = string.Empty; if (o != null) { Control ctl = o as Control; if (ctl.HasChildren) { result = string.Format("{0}={1}", ctl.Name, GetValue(ctl.Controls)); } else { result = string.Format("{0}={1}", ctl.Name, ctl.Text); } } return result; }; _specializedFuncMappings[typeof(DataRow)] = (o) => { string result = string.Empty; if (o != null) { DataRow row = o as DataRow; List list = new List (); foreach (DataColumn col in row.Table.Columns) { list.Add(string.Format("{0}", GetValue(row[col]))); } result = string.Join(",", list.ToArray()); result = string.Format("{0},[{1}]", result, row.RowState); } return result; }; _specializedFuncMappings[typeof(DataRowView)] = (o) => { string result = string.Empty; if (o != null) { DataRowView rowView = o as DataRowView; if (rowView.Row != null) { DataRow row = rowView.Row; result = GetValue(row); } } return result; }; _specializedFuncMappings[typeof(DataColumn)] = (o) => { string result = string.Empty; if (o != null) { DataColumn col = o as DataColumn; result = col.ColumnName; } return result; }; _specializedFuncMappings[typeof(DataTable)] = (o) => { string result = string.Empty; if (o != null) { DataTable tbl = o as DataTable; List colList = new List (); foreach (DataColumn col in tbl.Columns) { colList.Add(GetValue(col)); } List rowList = new List (); foreach (DataRow row in tbl.Rows) { rowList.Add(GetValue(row)); } result = string.Format("{0}{1}", string.Join(",", colList.ToArray()), Environment.NewLine); result += string.Join(Environment.NewLine, rowList.ToArray()); } return result; }; _specializedFuncMappings[typeof(BindingSource)] = (o) => { string result = string.Empty; if (o != null) { BindingSource bs = o as BindingSource; result = GetValue(bs.DataSource); } return result; }; } protected virtual void InitializeGenericFuncMappings() { if (_genericFuncMappings == null) { _genericFuncMappings = new Dictionary >(); } _genericFuncMappings[typeof(IList)] = (o) => { string result = string.Empty; if (o != null) { IList l = o as IList; List list = new List (); foreach (object elem in l) { list.Add(string.Format("({0})", GetValue(elem))); } result = string.Join(",", list.ToArray()); result = string.Format("[{0}]", result); } return result; }; _genericFuncMappings[typeof(IDictionary)] = (o) => { string result = string.Empty; if (o != null) { IDictionary dict = o as IDictionary; List list = new List (); foreach (object key in dict.Keys) { list.Add(string.Format("({0}={1})", GetValue(key), GetValue(dict[key]))); } result = string.Join(",", list.ToArray()); result = string.Format("{{{0}}}", result); } return result; }; _genericFuncMappings[typeof(ICollection)] = (o) => { string result = string.Empty; if (o != null) { ICollection collection = o as ICollection; List list = new List (); foreach (object elem in collection) { list.Add(string.Format("({0})", GetValue(elem))); } result = string.Join(",", list.ToArray()); result = string.Format("[{0}]", result); } return result; }; } protected virtual string GetValue(object o) { string result = string.Empty; result = GetValueCore(_specializedFuncMappings, o); if (string.IsNullOrEmpty(result)) { result = GetValueCore(_genericFuncMappings, o); if (string.IsNullOrEmpty(result)) { result = o.ToString(); } } return result; } protected virtual string GetValueCore(Dictionary > mapping, object o) { string result = string.Empty; Type objectType = o.GetType(); foreach (Type t in mapping.Keys) { if (t.IsAssignableFrom(objectType)) { result = mapping[t](o); break; } } return result; } #endregion } } #endregion
Gsf.Lib.Utils名前空間に含まれるクラスが混じってますが気にしないで下さい。
DataTableの出力をいちいち書くのが面倒なので、自分用のライブラリを貼り付けています。w
後、余談ですがDataRowの内容を別のDataRowと比較する際は、自前でループさせるより
DataRowComparer
*1:tbl) => {
tbl.Dump();
Console.WriteLine("");
});
//
// 同じデータか否か.
//
Console.WriteLine("table == table1 ?? => {0}", table.AsEnumerable().SequenceEqual(table2.AsEnumerable(), DataRowComparer