Эта строка уже относится к другой ошибке таблицы при попытке добавить строки?


197

У меня есть DataTable, в котором есть несколько строк, и я использую select для фильтрации строк, чтобы получить коллекцию DataRows, которые я затем перебираю, используя foreach, и добавляю его в другой DataTable, но он выдает мне ошибку «Эта строка уже принадлежит на другой стол ". Вот код:

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
отличный вопрос; Я запутался в строках и таблицах, принадлежащих другим контейнерам
Река Вивиан

Ответы:


339

Вам нужно создать новый Rowсо значениями из drпервых. А DataRowможет принадлежать только одному DataTable.

Вы также можете использовать Addкоторый принимает массив значений:

myTable.Rows.Add(dr.ItemArray)

Или, возможно, даже лучше:

// 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
Могу ли я использовать ImportRow в качестве оповещения? и почему .NET только не позволяет вам иметь один и тот же DataRow для разных DataTables? Это по замыслу?
Xaisoft

3
Хех, я только что понял ImportRow, отредактируй мой ответ, и вы все опередите меня. Но да, я бы порекомендовал такой подход, так как он скопирует строку для вас
JoshBerke

2
ImportRowЯ работаю на меня. Но добавить строки сделал! Thanksssssssssss
nawfal

1
ImportRow не будет работать, если импортируемая вами строка является ссылкой на строку в исходной таблице. ItemArray работает, если вы используете исходную строку, но вы должны не забыть добавить строку к месту назначения, прежде чем удалить строку из источника, в противном случае он жалуется, что строка была удалена и не может найти данные.
Адам Хоулдсворт

2
.ImportRow().Clone()изначально не работал для меня, потому что я не делал и не создавал столбцы в моем новом DataTable. Это пришло с 0, когда я посмотрел .Rows.Countна моем новом столе. Так как мне нужно было создать столбцы в моей таблице и добавить их, я просто создал NewRow()оператор и добавил свои значения непосредственно в столбцы этой новой строки и добавил эту строку в свою таблицу в цикле (см. Мой ответ ниже) ,
vapcguy

34

Попробуй это:

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

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

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

3
Спасибо за это .. хотя ответ, предоставленный @JoshBerke, был правильным, вам нужно клонировать исходную таблицу, как в вашем примере, чтобы она работала.
carny666

8
yourTable.ImportRow(dataRow);

Это потому, что строка, которую вы копируете, не совпадает TableName:

Например, попробуйте:

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

1
У меня тоже был стол с ошибочным названием. Спасибо!
Бруно

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

1
Я не думаю, что вы можете что-то добавить к тому, что вы повторяете, поскольку вы перебираете это.
vapcguy

3

Это не самое чистое / быстрое / простое / самое элегантное решение, но это грубая сила, которую я создал, чтобы выполнить работу в похожем сценарии:

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
}

Имена в DataColumns должны совпадать с именами в исходной таблице, чтобы она работала. Я просто использовал «ID» и «Имя» в качестве примеров.


1

Почему бы тебе просто не использовать CopyToDataTable

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

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

1
Что такое orderRows должен быть здесь?
Ави

Новый DataTable выбранных строк из dtAvi.
vapcguy

0

Вы можете дать некоторый идентификатор столбцам и назвать его уникально.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.