Ten wiersz należy już do innego błędu tabeli podczas próby dodania wierszy?


197

Mam DataTable, która ma kilka wierszy, i używam select do filtrowania wierszy, aby uzyskać kolekcję DataRows, które następnie przeglądam za pomocą foreach i dodam do innej DataTable, ale wyświetla błąd „Ten wiersz już należy do innego stołu ”. Oto kod:

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = new DataTable();

DataRow[] orderRows = dt.Select("CustomerID = 2");

foreach (DataRow dr in orderRows)
{
    dtSpecificOrders.Rows.Add(dr); //Error thrown here.
}

1
świetne pytanie; Mylę się co do wierszy i tabel należących do innych kontenerów
Vivian River

Odpowiedzi:


339

Musisz utworzyć nowy Rowz wartościami od drpierwszego. A DataRowmoże należeć tylko do jednego DataTable.

Możesz także użyć, Addktóry pobiera tablicę wartości:

myTable.Rows.Add(dr.ItemArray)

A może nawet lepiej:

// This works because the row was added to the original table.
myTable.ImportRow(dr);

// The following won't work. No data will be added or exception thrown.
var drFail = dt.NewRow()
drFail["CustomerID"] = "[Your data here]";
// dt.Rows.Add(row); // Uncomment for import to succeed.
myTable.ImportRow(drFail);

6
Czy mogę użyć ImportRow jako alternatywy? i dlaczego .NET miałby nie pozwalać tylko na posiadanie tego samego DataRow dla różnych DataTables? Czy to z założenia?
Xaisoft,

3
Heh Właśnie zdałem sobie sprawę z ImportRow, edytuj moją odpowiedź i wszyscy mnie pobili. Ale tak, poleciłbym to podejście, ponieważ skopiuje wiersz dla ciebie
JoshBerke

2
ImportRowpraca dla mnie. Ale Dodaj Wiersze tak! Thanksssssssssss
nawfal

1
ImportRow nie będzie działać, jeśli importowany wiersz jest odniesieniem do wiersza w tabeli źródłowej. ItemArray działa, jeśli korzystasz z wiersza źródłowego, ale musisz pamiętać, aby dodać wiersz do miejsca docelowego przed usunięciem wiersza ze źródła, w przeciwnym razie będzie to narzekać, że wiersz został usunięty i nie można znaleźć danych.
Adam Houldsworth,

2
.ImportRow()nie działało dla mnie, ponieważ początkowo nie tworzyłem .Clone()ani nie tworzyłem kolumn w moim nowym DataTable. Gdy spojrzałem .Rows.Countna mój nowy stół, pojawiło się 0 . Ponieważ musiałem utworzyć kolumny w mojej tabeli i dodać je, właśnie utworzyłem NewRow()instrukcję i dodałem swoje wartości bezpośrednio do kolumn w tym nowym wierszu i dodałem ten wiersz do mojej tabeli w pętli (patrz moja odpowiedź poniżej) .
vapcguy,

34

Spróbuj tego:

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = dt.Clone();

DataRow[] orderRows = dt.Select("CustomerID = 2");

foreach (DataRow dr in orderRows)
{
    dtSpecificOrders.ImportRow(dr);
}

3
Dziękujemy za to .. chociaż odpowiedź udzielona przez @JoshBerke była poprawna, musisz sklonować oryginalny stół, tak jak w twoim przykładzie, aby działał.
carny666

8
yourTable.ImportRow(dataRow);

Jest tak, ponieważ kopiowany wiersz nie ma tego samego TableName:

Na przykład spróbuj:

Table1.TableName = "Table1";
Table2.TableName = "Table2";

1
Miałem też źle nazwany stół. Dzięki!
Bruno,

3
foreach (DataRow dr in dtSpecificOrders.rows)
{
   dtSpecificOrders.Rows.Add(dr.ItemArray); 
}

1
Nie sądzę, abyś mógł dodać coś do tego, co iterujesz, ponieważ iterujesz przez to.
vapcguy

3

To nie jest najczystsze / najszybsze / najłatwiejsze / najbardziej eleganckie rozwiązanie, ale to brutalna siła, którą stworzyłem, aby wykonać zadanie w podobnym scenariuszu:

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = new DataTable();

// Create new DataColumns for dtSpecificOrders that are the same as in "dt"
DataColumn dcID = new DataColumn("ID", typeof(int));
DataColumn dcName = new DataColumn("Name", typeof(string));
dtSpecificOrders.Columns.Add(dtID);
dtSpecificOrders.Columns.Add(dcName);

DataRow[] orderRows = dt.Select("CustomerID = 2");

foreach (DataRow dr in orderRows)
{
    DataRow myRow = dtSpecificOrders.NewRow();  // <-- create a brand-new row
    myRow[dcID] = int.Parse(dr["ID"]);
    myRow[dcName] = dr["Name"].ToString();
    dtSpecificOrders.Rows.Add(myRow);   // <-- this will add the new row
}

Nazwy w DataColumns muszą pasować do nazw w oryginalnej tabeli, aby działało. Użyłem tylko „ID” i „Nazwa” jako przykładów.


1

Dlaczego po prostu nie użyjesz CopyToDataTable

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = new DataTable();

DataTable orderRows = dt.Select("CustomerID = 2").CopyToDataTable();

1
Co to jest orderRows?
Avi

Nowa tabela danych wybranych wierszy z dtAvi.
vapcguy

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.