Cette ligne appartient déjà à une autre erreur de table lorsque vous essayez d'ajouter des lignes?


197

J'ai un DataTable qui a quelques lignes et j'utilise la sélection pour filtrer les lignes pour obtenir une collection de DataRows que je boucle ensuite en utilisant foreach et l'ajoute à un autre DataTable, mais cela me donne l'erreur "Cette ligne appartient déjà à une autre table ". Voici le 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
grande question; Je suis confus au sujet des rangées et des tables appartenant à d'autres conteneurs
Vivian River

Réponses:


339

Vous devez d'abord créer un nouveau Rowavec les valeurs dr. Un DataRowne peut appartenir qu'à un seul DataTable.

Vous pouvez également utiliser Addce qui prend un tableau de valeurs:

myTable.Rows.Add(dr.ItemArray)

Ou probablement encore mieux:

// 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
Puis-je utiliser ImportRow comme alternative? et pourquoi .NET ne vous permettrait-il pas uniquement d'avoir le même DataRow pour différents DataTables? Est-ce par conception?
Xaisoft

3
Hé je viens de réaliser ImportRow, éditez ma réponse et vous m'avez tous battu. Mais oui, je recommanderais cette approche car elle copiera la ligne pour vous
JoshBerke

2
ImportRowdin travaille pour moi. Mais Add Rows l'a fait! Thanksssssssssss
nawfal

1
ImportRow ne fonctionnera pas si la ligne que vous importez est une référence à la ligne dans la table source. ItemArray fonctionne si vous utilisez la ligne source, mais vous devez vous rappeler d'ajouter la ligne à la destination avant de supprimer la ligne de la source, sinon il se plaint que la ligne a été supprimée et ne peut pas trouver les données.
Adam Houldsworth

2
.ImportRow()n'a pas fonctionné pour moi parce que je n'ai pas fait .Clone()ou créé de colonnes sur mon nouveau DataTable, au départ. Il est venu avec 0 quand j'ai regardé .Rows.Countsur ma nouvelle table. Puisque j'allais avoir besoin de créer des colonnes sur ma table et de les ajouter, je viens de créer une NewRow()instruction et d'ajouter mes valeurs aux colonnes de cette nouvelle ligne directement et d'ajouter cette ligne à ma table, dans la boucle (voir ma réponse ci-dessous) .
vapcguy

34

Essaye ça:

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

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

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

3
Merci pour cela .. bien que la réponse fournie par @JoshBerke soit correcte, vous devez cloner la table d'origine comme dans votre exemple pour que cela fonctionne.
carny666

8
yourTable.ImportRow(dataRow);

C'est parce que la ligne que vous copiez n'a pas la même chose TableName:

Par exemple, essayez:

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

1
J'avais aussi une table mal nommée. Merci!
Bruno

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

1
Je ne pense pas que vous puissiez ajouter quoi que ce soit à ce que vous répétez, car vous le répétez.
vapcguy

3

Ce n'est pas la solution la plus propre / la plus rapide / la plus facile / la plus élégante, mais c'est une solution de force brute que j'ai créée pour faire le travail dans un scénario similaire:

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
}

Les noms dans les DataColumns doivent correspondre à ceux de votre table d'origine pour que cela fonctionne. J'ai juste utilisé "ID" et "Nom" comme exemples.


1

Pourquoi n'utilisez-vous pas CopyToDataTable

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

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

1
Qu'est-ce que orderRows est censé être ici?
Avi

Un nouveau DataTable des lignes sélectionnées de dt, Avi.
vapcguy

0

vous pouvez donner un identifiant aux colonnes et le nommer de manière unique.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.