最初に宛先テーブルを作成し、(すべての入力テーブルの列数を合計して) 列を追加し、次に入力テーブルの各行の値の個々の配列を連結して行を追加します。
もちろん、結果の行には、DataTable
各入力テーブルのトップダウン方向に表示される値が含まれます (上に揃えられます)。また、結果の行数が最大の入力テーブルの行数であることも意味します。
最初に変数を初期化して入力しList<DataTable>
、次にこの変数をメソッド パラメーターとして使用して結合を実行します。
#region table collection initialization
List<DataTable> dts = new List<DataTable>();
var dt = new DataTable();
dt.Columns.Add("Test0", typeof(string));
dt.Rows.Add(1);
dt.Rows.Add(2);
dts.Add(dt);
dt = new DataTable();
dt.Columns.Add("Test1", typeof(int));
dt.Rows.Add(2);
dts.Add(dt);
dt = new DataTable();
dt.Columns.Add("Test3", typeof(int));
dt.Columns.Add("Test4");
dt.Columns.Add("Test5", typeof(int));
dt.Rows.Add(3, "a", 1);
dt.Rows.Add(4);
dt.Rows.Add(5, "a");
dt.Rows.Add(null, "a");
dts.Add(dt);
dt = new DataTable();
dt.Columns.Add("Test6", typeof(DateTime));
dt.Columns.Add("Test7", typeof(int));
dt.Rows.Add(DateTime.Now);
dts.Add(dt);
#endregion
// sample method usage
var result = GetJoinedTable(dts);
結果の結合されたテーブルを変数にGetJoinedTable
返すメソッドを作成しましょう。result
private DataTable GetJoinedTable(List<DataTable> dts)
{
var dest = new DataTable();
//will be used if you have non-unique column names
int counter = 0;
foreach (var column in dts
.SelectMany<DataTable, DataColumn>(t =>
t.Columns.Cast<DataColumn>()))
{
dest.Columns.Add(column.ColumnName, column.DataType);
// if you have non-unique column names use the following instead
//dest.Columns.Add(String.Format("column_{0}", counter++),
// column.DataType);
}
List<object> rowItems;
for (int i = 0; i < dts.Max(t => t.Rows.Count); i++)
{
rowItems = new List<object>();
for (int j = 0; j < dts.Count; j++)
{
if (dts[j].Rows.Count > i)
{
var r = dts[j].Rows[i].ItemArray
.Select((v, index) =>
(v == null || v == System.DBNull.Value)
? GetDefault(dts[j].Columns[index].DataType) : v);
rowItems.AddRange(r);
}
else
{
for (int c = 0; c < dts[j].Columns.Count; c++)
{
rowItems.Add(GetDefault(dts[j].Columns[c].DataType));
}
}
}
dest.Rows.Add(rowItems.ToArray());
}
return dest;
}
DataType
また、列のプロパティに基づいて、適切な既定の列値を返す次のメソッドを追加する必要があります。
object GetDefault(Type t)
{
if (t.IsValueType)
{
return Activator.CreateInstance(t);
}
else
{
return null;
}
}