Diese Zeile gehört bereits zu einem anderen Tabellenfehler, wenn versucht wird, Zeilen hinzuzufügen?


196

Ich habe eine DataTable, die einige Zeilen enthält, und ich verwende die Auswahl, um die Zeilen zu filtern, um eine Sammlung von DataRows zu erhalten, die ich dann mit foreach durchlaufe und zu einer anderen DataTable hinzufüge, aber es gibt mir den Fehler "Diese Zeile gehört bereits zu einem anderen Tisch ". Hier ist der Code:

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
große Frage; Ich bin verwirrt über Zeilen und Tabellen, die zu anderen Containern gehören
Vivian River,

Antworten:


338

Sie müssen zuerst eine neue Rowmit den Werten erstellen dr. A DataRowkann nur zu einer einzigen gehörenDataTable .

Sie können auch Addeine Reihe von Werten verwenden:

myTable.Rows.Add(dr.ItemArray)

Oder wahrscheinlich noch besser:

// 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
Kann ich ImportRow als Alternative verwenden? und Warum sollten Sie in .NET nicht nur dieselbe DataRow für verschiedene DataTables verwenden? Ist das beabsichtigt?
Xaisoft

3
Heh, ich habe gerade ImportRow realisiert, meine Antwort bearbeitet und ihr habt mich alle geschlagen. Aber ja, ich würde diesen Ansatz empfehlen, da er die Zeile für Sie
kopieren wird

2
ImportRowIch arbeite für mich. Aber Zeilen hinzufügen hat es getan! Thanksssssssssss
nawfal

1
ImportRow funktioniert nicht, wenn die von Ihnen importierte Zeile auf die Zeile in der Quelltabelle verweist. ItemArray funktioniert, wenn Sie die Quellzeile verwenden. Sie müssen jedoch daran denken, die Zeile zum Ziel hinzuzufügen, bevor Sie die Zeile aus der Quelle entfernen. Andernfalls wird beanstandet, dass die Zeile entfernt wurde und die Daten nicht gefunden werden können.
Adam Houldsworth

2
.ImportRow()hat bei mir nicht funktioniert, weil ich anfangs keine .Clone()Spalten in meiner neuen DataTable erstellt oder erstellt habe. Es kam mit 0, als ich .Rows.Countauf meinem neuen Tisch sah. Da ich Spalten in meiner Tabelle erstellen und hinzufügen musste, habe ich einfach eine NewRow()Anweisung erstellt und meine Werte direkt zu den Spalten in dieser neuen Zeile hinzugefügt und diese Zeile innerhalb der Schleife zu meiner Tabelle hinzugefügt (siehe meine Antwort unten). .
Vapcguy

34

Versuche dies:

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

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

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

3
Vielen Dank dafür. Obwohl die Antwort von @JoshBerke korrekt war, müssen Sie die ursprüngliche Tabelle wie in Ihrem Beispiel klonen, damit sie funktioniert.
carny666

8
yourTable.ImportRow(dataRow);

Dies liegt daran, dass die Zeile, die Sie kopieren, nicht dieselbe hat TableName :

Versuchen Sie zum Beispiel:

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

1
Ich hatte auch einen falsch benannten Tisch. Vielen Dank!
Bruno

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

1
Ich glaube nicht, dass Sie dem, was Sie iterieren, etwas hinzufügen können, während Sie es durchlaufen.
Vapcguy

3

Dies ist nicht die sauberste / schnellste / einfachste / eleganteste Lösung, aber es ist eine Brute-Force-Lösung, die ich erstellt habe, um die Arbeit in einem ähnlichen Szenario zu erledigen:

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
}

Die Namen in den DataColumns müssen mit denen in Ihrer Originaltabelle übereinstimmen, damit dies funktioniert. Ich habe nur "ID" und "Name" als Beispiele verwendet.


1

Warum benutzt du nicht einfach CopyToDataTable

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

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

1
Was soll orderRows hier sein?
Avi

Eine neue Datentabelle der ausgewählten Zeilen aus dtAvi.
Vapcguy

0

Sie können den Spalten eine ID geben und sie eindeutig benennen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.