Удаление определенных строк из DataTable - PullRequest
64 голосов
/ 13 апреля 2011

Я хочу удалить некоторые строки из DataTable, но выдает ошибку, подобную этой,

Коллекция была изменена;Операция перечисления может не выполняться

Я использую для удаления этого кода,

foreach(DataRow dr in dtPerson.Rows){
    if(dr["name"].ToString()=="Joe")
        dr.Delete();
}

Итак, в чем проблема и как ее исправить?Какой метод вы посоветуете?

Ответы [ 13 ]

0 голосов
/ 22 апреля 2019

Я вижу различные фрагменты правильного ответа здесь, но позвольте мне собрать все вместе и объяснить пару вещей.

Прежде всего, AcceptChanges следует использовать только для обозначениявся транзакция в таблице как проверенная и подтвержденная.Это означает, что если вы используете DataTable в качестве источника данных для привязки, например, к серверу SQL, то вызов AcceptChanges вручную гарантирует, что изменения никогда не будут сохранены на сервере SQL . * 1007.*

Что делает эту проблему более запутанной, так это то, что на самом деле есть два случая, в которых выдается исключение, и мы должны предотвратить оба из них.

1.Изменение коллекции IEnumerable

Мы не можем добавить или удалить индекс для перечисляемой коллекции, поскольку это может повлиять на внутреннюю индексацию перечислителя.Есть два способа обойти это: либо выполнить собственную индексацию в цикле for, либо использовать отдельную коллекцию (которая не изменяется) для перечисления.

2.Попытка чтения удаленной записи

Поскольку DataTables являются транзакционными коллекциями, записи можно пометить для удаления, но они по-прежнему появляются в перечислении.Это означает, что если вы запросите удаленную запись для столбца "name", он выдаст исключение.Это означает, что мы должны проверить, чтобы узнать dr.RowState != DataRowState.Deleted перед запросом столбца.

Собрать все вместе

Мы могли бы запутаться и сделать все это вручную, илимы можем позволить DataTable сделать всю работу за нас и сделать оператор похожим на вызов SQL, выполнив следующее:

string name = "Joe";
foreach(DataRow dr in dtPerson.Select($"name='{name}'"))
    dr.Delete();

При вызове функции DataTable Select наш запрос автоматически избегает ужеудаленные записи в DataTable.А поскольку функция Select возвращает массив совпадений, коллекция, которую мы перечисляем, не изменяется при вызове dr.Delete().Я также добавил в выражение Select строковую интерполяцию, чтобы можно было выбирать переменные без шума в коде.

0 голосов
/ 06 апреля 2019

Вы пытаетесь получить и удалить столбец идентификатора из таблицы данных

if (dt1.Columns.Contains("ID"))
{
    for (int i = dt1.Rows.Count - 1; i >= 0; i--)
    {
        DataRow dr = dt1.Rows[i];

        if (dr["ID"].ToString() != "" && dr["ID"].ToString() != null)
        {
            dr.Delete();
        }
    }

    dt1.Columns.Remove("ID");
}
0 голосов
/ 13 февраля 2015

В моем приложении есть набор данных, и я пошел вносить в него изменения (удаляя строку), но ds.tabales["TableName"] только для чтения.Тогда я нашел это решение.

Это приложение wpf C#,

try {
    var results = from row in ds.Tables["TableName"].AsEnumerable() where row.Field<string>("Personalid") == "47" select row;                
    foreach (DataRow row in results) {
        ds.Tables["TableName"].Rows.Remove(row);                 
    }           
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...