można najpierw utworzyć tabeli docelowej, należy dodać, że to kolumny (poprzez zsumowanie liczby kolumn we wszystkich tabelach wejściowych), a następnie dodać to wiersze przez konkatenację poszczególnych tablic wartości dla każdego wiersza w tabelach wejściowych.
Oczywiście wiersze wynikowego DataTable
będą zawierać wartości wyświetlane w kierunku od góry do dołu dla każdej tabeli wejściowej (wyrównane u góry). Oznacza to również, że liczba wynikowych wierszy jest liczbą wierszy w największej tabeli wejściowej.
Najpierw będziemy inicjować i wypełnić zmienną List<DataTable>
Pokochasz wykonujemy łączenia, stosując tę zmienną jako parametr metoda:
#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);
Stwórzmy metodę GetJoinedTable
który powróci do zmiennej result
uzyskany dołączył tabela:
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;
}
będziesz również dodać następującą metodę, która zwraca odpowiednią wartość domyślna kolumny, w oparciu o właściwość kolumny DataType
:
Dlaczego nie po prostu pętli nad wierszami w tabeli źródłowej i dla każdego wiersza, należy dodać odpowiednie kolumny do odpowiedniej tabeli docelowej? Wiersze i kolumny (w każdym rzędzie) mogą być iterowane. Byłoby trywialnie stworzyć Mapę Funkcji z SourceTable/row-> TargetTable/row. – user2246674