Skopiować wiersze z jednego Datatable do innego DataTable?


165

Jak mogę skopiować określone wiersze z DataTable do innego Datable w języku C #? Będzie więcej niż jeden wiersz.

Odpowiedzi:


257
foreach (DataRow dr in dataTable1.Rows) {
    if (/* some condition */)
        dataTable2.Rows.Add(dr.ItemArray);
}

Powyższy przykład zakłada, że dataTable1i dataTable2mają taką samą liczbę, typ i kolejność kolumn.


22
Czy to nie spowodowałoby, że „Ten wiersz należy już do innej tabeli”.
McArthey

15
@McArthey Nie, nie byłoby; tworzony jest nowy wiersz z wartości w istniejącym wierszu. Sam wiersz nie jest dodawany do innego DataTable.
Bradley Smith

20
@DawoodAbbasi Stanie się tak tylko wtedy, gdy pominiesz ItemArrayczęść na końcu wyrażenia. Upewnij się, że dodajesz wartości wiersza, a nie sam wiersz.
Bradley Smith,

4
@DawoodAbbasi Zapoznaj się z dokumentacją MSDN dotyczącą DataTable.Clonemetody: msdn.microsoft.com/en-us/library/…
Bradley Smith

10
Chociaż twoja odpowiedź jest poprawna technicznie, przykładowy kod nie odnosi się do twoich założeń. Odpowiedź @RageeshGr obsługuje wszystkie założenia, a IMHO jest napisane bardziej zwięźle i jest mniej podatne na błędy.
chris.nesbit1

94

Kopiuj określone wiersze z tabeli do innej

// here dttablenew is a new Table  and dttableOld is table Which having the data 

dttableNew  = dttableOld.Clone();  

foreach (DataRow drtableOld in dttableOld.Rows)
{
   if (/*put some Condition */)
   {
      dtTableNew.ImportRow(drtableOld);
   }
}

Jeśli nie muszę już używać dttableOld po zaimportowaniu, czy nadal muszę używać Clone ()?
Sam

Świetnie i praktycznie! Dzięki!
Mayer Spitzer

1
@Sam co do twojego pytania, Clone ma skopiować strukturę tabeli, jeśli twoja tabela ma już ten sam typ danych, nie potrzebujesz jej.
Mayer Spitzer

19

Spróbuj tego

    String matchString="ID0001"//assuming we have to find rows having key=ID0001
    DataTable dtTarget = new DataTable();
    dtTarget = dtSource.Clone();
    DataRow[] rowsToCopy;
    rowsToCopy = dtSource.Select("key='" + matchString + "'");
    foreach (DataRow temp in rowsToCopy)
    {
        dtTarget.ImportRow(temp);
    }

@ManojSavalia, więc jaka jest alternatywa, która nie kosztuje wydajności?
Sam

16

Sprawdź to, może ci się spodobać (poprzednio sklonuj tabelę 1 do tabeli 2):

table1.AsEnumerable().Take(recodCount).CopyToDataTable(table2,LoadOption.OverwriteChanges);

Lub:

table1.AsEnumerable().Where ( yourcondition  ) .CopyToDataTable(table2,LoadOption.OverwriteChanges);

Jest to znacznie lepsze podejście, ponieważ wykorzystuje wbudowaną możliwość kopiowania zakresu lub nawet wybierania wierszy z jednego DataTable do drugiego bez jawnego iterowania przez każdy, w przeciwieństwie do wszystkich pętli foreach, odpowiedzi opartych na metodzie .ForEach.
David Burg

15

Obsługiwane w: 4, 3.5 SP1, możesz teraz po prostu wywołać metodę na obiekcie.

DataTable dataTable2 = dataTable1.Copy()

2
Technicznie tworzy to kopię pliku danych. Chociaż nie zostało to wyraźnie określone w pytaniu, możliwe, że dataTable2 już istnieje i zawiera inne wiersze, których nie chcemy utracić. Ponadto pytanie konkretnie określa „określone wiersze”, podczas gdy dotyczy to tylko wszystkich wierszy.
Matt

5

W wyniku pozostałych postów jest to najkrótszy jaki udało mi się uzyskać:

DataTable destTable = sourceTable.Clone();
sourceTable.AsEnumerable().Where(row => /* condition */ ).ToList().ForEach(row => destTable.ImportRow(row));

Co jest w zasadzie foreach. Ponadto nie filtrujesz według warunku, zgodnie z żądaniem OP.
Eric Wu,

Teraz, jeśli wyczyszczę sourceTabletestament, destTablerównież wyczyszczę?
Si8

Chcę mieć możliwość przypisania wartości i wyczyszczenia oryginalnej zmiennej bez czyszczenia miejsca docelowego.
Si8

2

poniższa próbka byłaby najszybszym sposobem skopiowania jednego wiersza. każda komórka jest kopiowana na podstawie nazwy kolumny. w przypadku, gdy nie potrzebujesz określonej komórki do skopiowania, spróbuj złapać lub dodać jeśli. jeśli zamierzasz skopiować więcej niż 1 wiersz, zapętl poniższy kod.

DataRow dr = dataset1.Tables[0].NewRow();
for (int i = 0; i < dataset1.Tables[1].Columns.Count; i++)
{
    dr[dataset1.Tables[1].Columns[i].ColumnName] = dataset1.Tables[1].Rows[0][i];
}

datasetReport.Tables[0].Rows.Add(dr);

dataset1.Tables [1] .Rows [ 0 ] [i]; zmień indeks 0 na określony indeks wiersza lub możesz użyć zmiennej, jeśli zamierzasz zapętlić się lub jeśli będzie to logiczne


1
 private void CopyDataTable(DataTable table){
     // Create an object variable for the copy.
     DataTable copyDataTable;
     copyDataTable = table.Copy();
     // Insert code to work with the copy.
 }

twój kod działa idealnie dla mnie, jest bardzo prostym kodem, dzięki
Esraa_92

1

Dla tych, którzy chcą zapytać SQL o jedno polecenie:

INSERT INTO TABLE002 
(COL001_MEM_ID, COL002_MEM_NAME, COL002_MEM_ADD, COL002_CREATE_USER_C, COL002_CREATE_S)
SELECT COL001_MEM_ID, COL001_MEM_NAME, COL001_MEM_ADD, COL001_CREATE_USER_C, COL001_CREATE_S
FROM TABLE001;

To zapytanie skopiuje dane z TABLE001do TABLE002i zakładamy, że obie kolumny mają różne nazwy kolumn.

Nazwy kolumn są odwzorowywane jeden do jednego, na przykład:

COL001_MEM_ID -> COL001_MEM_ID

COL001_MEM_NAME -> COL002_MEM_NAME

COL001_MEM_ADD -> COL002_MEM_ADD

COL001_CREATE_USER_C -> COL002_CREATE_USER_C

COL002_CREATE_S -> COL002_CREATE_S

Możesz również określić klauzulę where, jeśli potrzebujesz jakiegoś warunku.


0

Aby skopiować całe dane, po prostu zrób to:

DataGridView sourceGrid = this.dataGridView1;
DataGridView targetGrid = this.dataGridView2;
targetGrid.DataSource = sourceGrid.DataSource;

2
pytanie dotyczy tego, jak skopiować określone wiersze z tabeli danych, a nie całość.
jtate

0

Stworzyłem łatwy sposób rozwiązania tego problemu

 DataTable newTable = oldtable.Clone();    
 for (int i = 0; i < oldtable.Rows.Count; i++)
 {
   DataRow drNew = newTable.NewRow();    
   drNew.ItemArray = oldtable.Rows[i].ItemArray;    
   newTable.Rows.Add(drNew);   
 } 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.