Подтвердить что ты не робот

DataTable, Как условно удалить строки

Я занимаюсь учебным процессом на С#, и до сих пор все хорошо. Я, однако, сейчас ударил свой первый "скажи что?" момент.

DataTable предлагает случайный доступ к рядам для коллекции Rows, а не только через типичное поведение коллекций, но также и через DataTable.Select. Однако я не могу привязать эту способность к DataRow.Delete. Пока что мне кажется, что мне нужно сделать, чтобы условно удалить одну или несколько строк из таблицы.

int max = someDataTable.Rows.Count - 1;
for(int i = max; i >= 0; --i)
{
    if((int)someDataTable.Rows[i].ItemArray[0] == someValue)
    {
        someDataTable.Rows[i].BeginEdit();
        someDataTable.Rows[i].Delete();
    }
    else
        break;
}
someDataTable.AcceptChanges();

Но я не доволен этим кодом. Я тоже не уверен. Я должен что-то упустить. Действительно ли я вынужден последовательно ударять по рядам, если мне нужно удалить одну или несколько строк условно?

(не обращайте внимания на инвертированное для. Я удаляю с конца datatable. Так что это нормально)

4b9b3361

Ответ 1

Вы можете запросить набор данных и затем закодировать выбранные строки, чтобы установить их как delete.

var rows = dt.Select("col1 > 5");
foreach (var row in rows)
    row.Delete();

... и вы также можете создать некоторые методы расширения, чтобы упростить его...

myTable.Delete("col1 > 5");

public static DataTable Delete(this DataTable table, string filter)
{
    table.Select(filter).Delete();
    return table;
}
public static void Delete(this IEnumerable<DataRow> rows)
{
    foreach (var row in rows)
        row.Delete();
}

Ответ 2

Здесь один-линейный, использующий LINQ, и избегая любой оценки времени выполнения строк выбора:

someDataTable.Rows.Cast<DataRow>().Where(
    r => r.ItemArray[0] == someValue).ToList().ForEach(r => r.Delete());

Ответ 3

У меня нет окна, пригодного для этого, но я думаю, что вы можете использовать DataView и делать что-то вроде этого:

DataView view = new DataView(ds.Tables["MyTable"]);
view.RowFilter = "MyValue = 42"; // MyValue here is a column name

// Delete these rows.
foreach (DataRowView row in view)
{
  row.Delete();
}

Я не тестировал это. Вы можете попробовать.

Ответ 4

Метод расширения на основе Linq

public static void DeleteRows(this DataTable dt, Func<DataRow, bool> predicate)
{
    foreach (var row in dt.Rows.Cast<DataRow>().Where(predicate).ToList())
        row.Delete();
}

Затем используйте:

DataTable dt = GetSomeData();
dt.DeleteRows(r => r.Field<double>("Amount") > 123.12 && r.Field<string>("ABC") == "XYZ");