42

我正在从事 C# 学习过程,到目前为止进展顺利。然而,我刚刚击中了我的第一个“说什么?” 片刻。

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();

但我对这段代码不满意。我也不相信。我肯定错过了什么。如果我需要有条件地删除一行或多行,我真的被迫按顺序点击 Rows 集合吗?

(不要介意倒置。我从数据表的末尾删除。所以没关系)

4

4 回答 4

77

您可以查询数据集,然后循环选定的行以将它们设置为删除。

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();
}
于 2009-10-20T00:19:19.767 回答
45

这是一个使用 LINQ 并避免对选择字符串进行任何运行时评估的单行代码:

someDataTable.Rows.Cast<DataRow>().Where(
    r => r.ItemArray[0] == someValue).ToList().ForEach(r => r.Delete());
于 2012-05-07T19:38:10.380 回答
10

我没有方便的 Windows 框来尝试此操作,但我认为您可以使用 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();
}

不过,我还没有测试过。你可以试一试。

于 2009-10-20T00:23:18.723 回答
1

基于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");
于 2017-04-08T12:47:19.177 回答