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. Так что это нормально)
Ответы
Ответ 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");