2009-04-06 2 views
157

J'ai un DataTable qui a quelques lignes et j'utilise le select pour filtrer les lignes pour obtenir une collection de DataRows que je boucle ensuite en utilisant foreach et l'ajoute à un autre DataTable, mais il me donne l'erreur "This Row appartient déjà à une autre table ". Voici le code:Cette ligne appartient déjà à une autre erreur de table lors de l'ajout de lignes?

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

bonne question; Je suis confus au sujet des lignes et des tables appartenant à d'autres conteneurs. –

Répondre

279

Vous devez créer une nouvelle avec les valeurs de dr premier. Un DataRow ne peut appartenir qu'à un seul DataTable.

Vous pouvez également utiliser Add 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); 
+5

Puis-je utiliser ImportRow en tant qu'alernative? Pourquoi le .NET ne vous permet-il pas d'avoir le même DataRow pour différents DataTables? Est-ce par conception? – Xaisoft

+0

Merci pour l'extrait ci-dessus. J'étais sur le point de demander si j'avais 100 rangées, est-ce que je devrais les taper toutes? – Xaisoft

+3

Heh Je viens de réaliser ImportRow, éditer ma réponse et vous m'avez tous battu. Mais oui, je recommande cette approche car elle va copier la ligne pour vous – JoshBerke

20

Essayez ceci:

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 était correcte, vous devez cloner la table d'origine comme dans votre exemple pour que cela fonctionne. – carny666

7
yourTable.ImportRow(dataRow); 

C'est parce que la rangée que vous copiez n'a pas la même TableName:

Par exemple, essayez:

Table1.TableName = "Table1"; 
Table2.TableName = "Table2"; 
+1

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

1
foreach (DataRow dr in dtSpecificOrders.rows) 
{ 
    dtSpecificOrders.Rows.Add(dr.ItemArray); 
} 
+0

Je ne pense pas que vous puissiez ajouter quoi que ce soit à ce que vous répétez, car vous l'itérez. – vapcguy

1

Pourquoi ne pas simplement utiliser 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

+0

Un nouveau DataTable des lignes sélectionnées à partir de 'dt', Avi. – vapcguy

3

Ce n'est pas le plus propre/le plus rapide/solution la plus simple/la plus élégante, mais c'est une 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 des colonnes de données doivent correspondre à ceux de votre table d'origine pour que cela fonctionne. J'ai simplement utilisé "ID" et "Name" comme exemples.

0

vous pouvez donner un identifiant aux colonnes et le nommer uniquement.

Questions connexes