Esta linha já pertence a outro erro de tabela ao tentar adicionar linhas?


197

Eu tenho um DataTable que possui algumas linhas e estou usando o select para filtrar as linhas para obter uma coleção de DataRows que, em seguida, percorre usando o foreach e o adiciono a outro DataTable, mas está me dando o erro "Esta linha já pertence para outra mesa ". Aqui está o código:

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
ótima pergunta; I ficar confuso sobre linhas e tabelas que pertencem a outros recipientes
Vivian Rio

Respostas:


339

Você precisa criar um novo Rowcom os valores do drprimeiro. A DataRowsó pode pertencer a um único DataTable.

Você também pode usar o Addque aceita uma matriz de valores:

myTable.Rows.Add(dr.ItemArray)

Ou provavelmente ainda melhor:

// 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 usar o ImportRow como um alernativo? e Por que o .NET não apenas permite que você tenha o mesmo DataRow para diferentes DataTables? Isso é intencional?
Xaisoft 06/04

3
Heh, eu acabei de perceber o ImportRow, editar minha resposta e todos vocês me superaram. Mas sim eu recomendo essa abordagem como ele irá copiar a linha para você
JoshBerke

2
ImportRowdin trabalho para mim. Mas Add Rows fez! Thanksssssssssss
Nawfal

1
O ImportRow não funcionará se a linha importada for uma referência à linha na tabela de origem. O ItemArray funciona se você usar a linha de origem, mas lembre-se de adicionar a linha ao destino antes de removê-la da fonte, caso contrário, ela reclama que a linha foi removida e não consegue encontrar os dados.
Adam Houldsworth

2
.ImportRow()não funcionou para mim porque não .Clone()criei ou criei colunas no meu novo DataTable, inicialmente. Ele veio com 0 quando eu olhei na .Rows.Countminha nova mesa. Como eu precisava criar colunas na minha tabela e adicioná-las, criei uma NewRow()instrução e adicionei meus valores diretamente às colunas da nova linha e adicionei essa linha à minha tabela, dentro do loop (veja minha resposta abaixo) .
vapcguy

34

Tente o seguinte:

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

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

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

3
Obrigado por isso .. embora a resposta fornecida por @JoshBerke esteja correta, você precisa clonar a tabela original, como no seu exemplo, para que ela funcione.
carny666

8
yourTable.ImportRow(dataRow);

É porque a linha que você está copiando não tem o mesmo TableName:

Por exemplo, tente:

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

1
Eu também tinha uma mesa com nome errado. Obrigado!
de Bruno

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

1
Não acho que você possa adicionar algo ao que está iterando, como você está iterando através dele.
vapcguy

3

Esta não é a solução mais limpa / mais rápida / mais fácil / mais elegante, mas é uma força bruta que eu criei para realizar o trabalho em um cenário semelhante:

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
}

Os nomes nas DataColumns devem corresponder aos da tabela original para que funcione. Eu apenas usei "ID" e "Nome" como exemplos.


1

Por que você não usa apenas CopyToDataTable

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

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

1
O que o orderRows deveria estar aqui?
Avi

Um novo DataTable das linhas selecionadas de dt, Avi.
vapcguy

0

você pode dar algum ID para as colunas e nomeá-lo exclusivamente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.