Questa riga appartiene già a un altro errore della tabella quando si tenta di aggiungere righe?


197

Ho una DataTable che ha alcune righe e sto usando la selezione per filtrare le righe per ottenere una raccolta di DataRows che poi eseguo in loop usando foreach e aggiungo a un'altra DataTable, ma mi sta dando l'errore "Questa riga appartiene già ad un altro tavolo ". Ecco il codice:

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
grande domanda; Mi confondo sulle file e le tabelle appartenenti ad altri container
fiume Vivian il

Risposte:


339

Devi crearne uno nuovo Rowcon i valori dal drprimo. A DataRowpuò appartenere solo a un singolo DataTable.

È inoltre possibile utilizzare Addche accetta una matrice di valori:

myTable.Rows.Add(dr.ItemArray)

O probabilmente anche meglio:

// 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
Posso usare ImportRow come alernativo? e perché .NET non consentirebbe solo di avere lo stesso DataRow per diverse DataTable? Questo è di progettazione?
Xaisoft,

3
Heh ho appena realizzato ImportRow, modifica la mia risposta e mi hai battuto tutti. Ma sì, consiglierei questo approccio in quanto copierà la riga per te
JoshBerke,

2
ImportRowdin lavoro per me. Ma Add Rows l'ha fatto! Thanksssssssssss
nawfal

1
ImportRow non funzionerà se la riga importata è un riferimento alla riga nella tabella di origine. ItemArray funziona se si utilizza la riga di origine, ma è necessario ricordare di aggiungere la riga alla destinazione prima di rimuovere la riga dall'origine, altrimenti si lamenta che la riga è stata rimossa e non è possibile trovare i dati.
Adam Houldsworth l'

2
.ImportRow()non ha funzionato per me perché non ho fatto .Clone()né creato colonne sulla mia nuova DataTable, inizialmente. Mi è venuta in mente 0 quando ho guardato .Rows.Countil mio nuovo tavolo. Dato che avrei dovuto creare colonne sulla mia tabella e aggiungerle, ho appena creato NewRow()un'istruzione e ho aggiunto i miei valori alle colonne su quella nuova riga direttamente e ho aggiunto quella riga alla mia tabella, all'interno del ciclo (vedi la mia risposta di seguito) .
vapcguy,

34

Prova questo:

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

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

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

3
Grazie per questo .. anche se la risposta fornita da @JoshBerke era corretta, è necessario clonare la tabella originale come nell'esempio affinché funzioni.
carny666,

8
yourTable.ImportRow(dataRow);

È perché la riga che stai copiando non ha lo stesso TableName:

Ad esempio, prova:

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

1
Anch'io avevo un tavolo sbagliato. Grazie!
Bruno,

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

1
Non penso che tu possa aggiungere nulla a ciò che stai ripetendo, mentre lo stai ripetendo.
vapcguy,

3

Questa non è la soluzione più pulita / più veloce / più semplice / più elegante, ma è una forza bruta che ho creato per svolgere il lavoro in uno scenario simile:

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
}

I nomi in DataColumns devono corrispondere a quelli nella tabella originale affinché funzioni. Ho appena usato "ID" e "Nome" come esempi.


1

Perché non usi semplicemente CopyToDataTable

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

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

1
Cosa dovrebbe essere qui OrderRows?
Avi,

Una nuova DataTable delle righe selezionate da dt, Avi.
vapcguy,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.