Как удалить DataColumn из DataTable программно

1

у меня есть код

foreach (DataColumn dataTableCol in this.dataTable.Columns)
            {
                bool columnFound = false;
                foreach (GRTColumnView uiColumn in descriptor.UIColumns)
                {
                    if (dataTableCol.ColumnName.Equals(uiColumn.Name))
                    {
                        columnFound = true;
                        break;
                    }
                }

                if (!columnFound)
                {
                    if (this.dataTable.Columns.Contains(dataTableCol.ColumnName))
                        this.dataTable.Columns.Remove(dataTableCol.ColumnName);
                }

            }

Я хочу удалить некоторые "вещи" из коллекции, если они не найдены в другой коллекции.

Когда я запускаю указанную выше программу, я получаю

Итерация может не выполняться по мере изменения коллекции

"Коллекция была изменена" - Coz удалили, должно быть, ударили

Каков способ достичь такого?

То, что я могу придумать, - это отметить все "вещи" для удаления, а затем

foreach( aThing in all_things_to_remove)
     remove_from_collection(aThing)

Но выше не кажется хорошим способом для меня, поскольку я должен сделать еще один цикл и использовать дополнительную память

  • 1
    цикл назад ...
  • 0
    @Plutonix Как это? for(inedx = this.dataTable.Columns.Count - 1 ; index >= 0 ; index++) или есть лучший способ?
Теги:
collections
datatable

4 ответа

3
Лучший ответ

В этом конкретном случае, когда вы перебираете небольшую коллекцию, содержащую несколько столбцов, вы можете просто создать новую коллекцию (через ToList()), чтобы вы не повторяли одну и ту же коллекцию, которую вы изменяете:

foreach (var dataTableCol in dataTable.Columns.Cast<DataColumn>().ToList())
{
    ...

    dataTable.Columns.Remove(dataTableCol.ColumnName);
}

Рекомендуемый способ, особенно если коллекция является большой, состоит в том, чтобы перечислить назад:

for (var i = dataTable.Columns.Count - 1; i >= 0; i--)
{
    ...

    dataTable.Columns.Remove(dataTable.Columns[i].ColumnName);
}
  • 0
    Спасибо за ответ. В моем случае, как вы сказали, коллекция маленькая, но что если моя коллекция была большой? Был бы выход, чтобы избежать копирования?
0
if (dt.Columns.Contains("RecordID")){
                    dt.Columns.Remove("RecordID");
                    dt.AcceptChanges();
                }
0

другой способ понижает индекс после удаления столбца.

for (int i = 0; i < datatable.Columns.Count; i++)
            {
                if (datatable.Columns[i].ColumnName.Contains("Column"))
                {
                    datatable.Columns.RemoveAt(i);
                    i--;
                }
            }
0

Вы не можете удалять элементы из коллекции, перечисляя ее с помощью цикла foreach. Создайте копию коллекции, используя Collection.ToArray() и запустите вас для копирования на копию и удалите свой предмет из фактической коллекции.

Поскольку DataTable.Columns не имеет ToArray или ToList, вы можете использовать метод CopyTo() и скопировать все столбцы в ColumnsArray.

Если вы не хотите создавать копию, вы можете использовать для цикла вместо цикла foreach. Вы можете отредактировать код таким образом:

for (int i = 0; i < dataTable.Columns.Count; i++)
{
    bool columnFound = false;
    foreach (GRTColumnView uiColumn in descriptor.UIColumns)
    {
        if (dataTable.Columns[i].Name.Equals(uiColumn.Name))
        {
            columnFound = true;
            break;
        }
    }

    if (!columnFound)
    {
        if (this.dataTable.Columns.Contains(dataTableCol.ColumnName))
            this.dataTable.Columns.Remove(dataTableCol.ColumnName);
    }

}
  • 0
    Ну, я знаю это по ошибке. Я спрашиваю выход. И, как вы предлагаете, я уже указал аналогичный подход в моем вопросе, и это не звучит мне хорошо
  • 0
    Это не будет работать правильно. Если вы не перечислите в обратном порядке, все остальные столбцы будут удалены (пропущены все остальные столбцы). По сути, если у вас есть 6 столбцов и вы пытаетесь удалить их все с помощью цикла for как это, вы удалите только 3 из них.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню