2013-06-04 13 views
6

Mam kilka DataTable's i muszę skopiować je do innej DataTable. Na przykład, jak widać na załączonym obrazku, muszę pobrać wszystkie dane z tabeli źródłowej 1 i skopiować je w dwóch pierwszych kolumnach tabeli docelowej, skopiować tabelę źródłową 2 w dwóch kolejnych kolumnach itd. . Jak można to łatwo osiągnąć?Kopiuj datatable jako kolumny w innym datatable

enter image description here

Edit: muszę przeczytać kilka plików Excel (mam przechowywania każdego pliku w DataTable) i nie będę wiedział dokładnie ile źródło tabela mam, więc to musi być zrobić jakoś dynamicznie.

+0

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

Odpowiedz

6

Zakładając, że tabele źródłowe mają taką samą strukturę można użyć Table.Copy() stworzyć tabelę dest, a następnie skopiować dane w pętli:

List<DataTable> sourceTables = getYourSourceTablesMethod(); 
if (sourceTables.Length>0) 
{ 
    DataTable destTable = sourceTables[0].Copy(); 

    for (int i = 1; i < sourceTables; i++) 
    { 
     foreach (DataRow drow in sourceTables[i].Rows) 
     destTable.Rows.Add(drow.ItemArray); 
    } 
} 
+1

Powód zaniechania? – Alex

0

Można strzelać zapytań typu:

select col1,col2 into sourcetable1 from destTable 
union 
select col3,col4 into sourcetable2 from destTable 
union 
select col5,col6 into sourcetable3 from destTable 
union 
select col7,col8 into sourcetable4 from destTable 

Albo może obserwować technikę wspomniano powyżej here.

W przypadku wierszy danych, może to być:

foreach (DataRow row in DestTable) 
{ 
    SourceTable1.ImportRow(row); 
} 
+0

Działa świetnie .. w SQL. Działa w DataTables? (DataTables nie * wymaga * pochodzić z SQL.) – user2246674

1

powinieneś znaleźć związek B etween tej tabeli źródłowej. Na przykład, mają ten sam identyfikator, można skopiować je tak

insert into destTable( 
select s1.col1, s1.col2, s2.col3, s2.col4, s3.col5, s3.col6, s4.col7, s4.col8 
from sourcetable1 s1, sourcetable2 s2, sourcetable3 s3, sourcetable4 s4 
where s1.id = s2.id and s2.id = s3.id and s3.id = s4.id) 
0

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: