今回は、結果を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() {
//
// エンジンを構築.
//
FileHelperEngine engine = 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