Как удалить несколько строк в DataTable? - PullRequest
30 голосов
/ 26 мая 2010

Как я могу удалить определенные DataRows в цикле строк DataTable, которые удовлетворяют пользовательскому условию - скажем, строки, имеющие индекс четного числа -? (Без использования LINQ)

Спасибо

Ответы [ 10 ]

57 голосов
/ 26 мая 2010

Это зависит от того, что вы подразумеваете под "удалить".

Если вы хотите пометить их как удаленные , просто вызовите метод Delete() в каждой строке, когда вы посещаете его в цикле. Затем вам нужно вызвать AcceptChanges() для таблицы данных, чтобы завершить удаление - предположительно, после обновления базы данных (если она задействована).

foreach( DataRow row in someTable.Rows )
{
    if( /* your condition here */ )
        row.Delete();
}
someTable.AcceptChanges();

Если вы хотите удалить его из таблицы данных, то вам нужно сделать это в два этапа:

List<DataRow> rowsToDelete = new List<DataRow>();
foreach( DataRow row in someTable.Rows )
{
    if( /* your condition here */ )
    {
        rowsToDelete.Add( row );
    }
}

foreach( DataRow row in rowsToDelete )
{
    someTable.Rows.Remove( row );
}

Стоит отметить, что вы всегда можете использовать первый метод для удаления строк - поскольку пометка строк как Deleted и последующее принятие изменений автоматически удаляют их из таблицы. Но иногда проще и эффективнее просто удалить объекты DataRow из коллекции Rows.

9 голосов
/ 26 мая 2010

Попробуйте что-то вроде этого примера

DataTable table = new DataTable();
table.Columns.Add("Foo",typeof(int));
for (int i = 0; i < 10; i++)
    table.Rows.Add(i);

for (int i = table.Rows.Count -1; i >=0; i--)
{
    // sample removes all even foos
    if ((int)table.Rows[i]["Foo"] % 2 == 0)
        table.Rows.RemoveAt(i);
}
4 голосов
/ 11 августа 2015

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

dt.Select("Column1 > 0").ToList.ForEach(Sub(x) dt.Rows.Remove(x))
4 голосов
/ 23 сентября 2010

Другой способ -

    DataRow[] DrArrCheck = DataTableName.Select("ID > 0");
    foreach(DataRow DrCheck in DrArrCheck)
    {
        DataTableName.Rows.Remove(DrCheck);
    }
1 голос
/ 01 февраля 2017

Чтобы удалить несколько строк (например, 50 000 из 100 000), гораздо быстрее скопировать базу данных, чем сделать либо datatable.Rows.Remove (row), либо row.Delete (). Например:

DataRow[] rowsToKeep = datatable.Select("ID > 50000");
DataTable tempDataTable= rowsToKeep.CopyToDataTable;
dataTable.Clear();
dataTable.Merge(tempDataTable);
tempDataTable.Dispose();
1 голос
/ 28 июля 2011
 public static void DeleteRowsFromDataTable(DataTable dataTable, string columnName, string columnValue)
        {
            IEnumerable<DataRow> dataRows = (from t in dataTable.AsEnumerable()
                                             where t.Field<string>(columnName) == columnValue
                                             select t);
            foreach (DataRow row in dataRows)
                dataTable.Rows.Remove(row);
        }
0 голосов
/ 09 апреля 2014

Я всегда использовал «двухфазный» подход Л.Бушкина и наконец решил, что стоило написать для него функцию:

    public delegate bool DataRowComparer(DataRow dr);

    public static void RemoveDataRows(DataTable table, DataRowComparer drc)
    {
        List<DataRow> RowsToRemove = new List<DataRow>();
        foreach (DataRow dr in table.Rows)
            if (drc(dr))
                RowsToRemove.Add(dr);
        foreach (DataRow dr in RowsToRemove)
            table.Rows.Remove(dr);
    }

А теперь я могу удалить строки с одной строкой кода (например):

RemoveDataRows(dt, row => row["StringVal"].ToString() == "B" && (Int16)(row["NumberVal"]) >= 4);

На случай, если это кому-нибудь поможет ...

(И любые способы дальнейшего сокращения приветствуются.)

0 голосов
/ 06 декабря 2012

Вот как я это сделал, когда столкнулся с этой проблемой.

Dim index As Integer = 0
Dim count As Integer = resultsDT.Rows.Count - 1
For i As Integer = 0 To count
    If resultsDT.Rows(index).Item("something") = "something" Then                               
        resultsDT.Rows(index).Delete()
        resultsDT.AcceptChanges()
        index = index - 1
    End If
    index = index + 1
    i = i + 1
Next
0 голосов
/ 26 мая 2010

попробуйте

foreach(DataRow oRow in YourDataTable.Rows)
{
  if ("Check You Condition")
   {
      YourDataTable.Rows.Remove(oRow);
   }
}
0 голосов
/ 26 мая 2010

попробуйте перебрать результат Select (). Это очень похоже на другие ответы, но я считаю, что это самый прямой

DataRow[] r = table.Select();
for (int i = 0; i < r.Length; i++)
{
    if (i % 2 == 0)
        r[i].Delete();
}
...