如何删除DataTable中的多行?

时间:2010-05-26 13:08:58

标签: c# .net ado.net datatable datarow

如何在符合自定义条件的DataTable行的循环中删除特定的DataRows -lets表示索引为偶数的行? (不使用LINQ)

由于

11 个答案:

答案 0 :(得分:57)

取决于“删除”的含义。

如果您的意思是将其标记为已删除,则只需在循环中访问每行时调用Delete()方法。然后,您需要在数据表上调用AcceptChanges()来完成删除 - 可能是在您更新数据库(如果涉及到数据库)之后。

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

如果你的意思是从DataTable中删除它,那么你需要两次通过:

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个对象就更清晰有效。

答案 1 :(得分:9)

尝试类似这样的例子

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

答案 2 :(得分:4)

另一种方式是

    DataRow[] DrArrCheck = DataTableName.Select("ID > 0");
    foreach(DataRow DrCheck in DrArrCheck)
    {
        DataTableName.Rows.Remove(DrCheck);
    }

答案 3 :(得分:4)

如果您想要比上面提出的解决方案更短的解决方案,请尝试循环结果列表,并使用 lambda (如sub(x))删除每一行。

dt.Select("Column1 > 0").ToList.ForEach(Sub(x) dt.Rows.Remove(x))

答案 4 :(得分:1)

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

答案 5 :(得分:1)

要删除多行(例如100,000个中的50,000个),复制数据库比执行datatable.Rows.Remove(row)或row.Delete()要快得多。例如:

DataRow[] rowsToKeep = datatable.Select("ID > 50000");
DataTable tempDataTable= rowsToKeep.CopyToDataTable;
dataTable.Clear();
dataTable.Merge(tempDataTable);
tempDataTable.Dispose();

答案 6 :(得分:0)

尝试迭代Select()的结果。这与其他答案非常相似,但我发现它是最直接的

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

答案 7 :(得分:0)

我总是使用LBushkin的“两阶段”方法,最后我决定为它编写一个函数是值得的:

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

如果这有助于任何人...

(任何进一步缩写的方法都会受到赞赏。)

答案 8 :(得分:0)

我就是这样做的。

    for (int i = RowNumber.Count - 1; i >= 0; i--)
                        {
                            dt.Rows.RemoveAt(Int32.Parse(RowNumber[i]));
                        }

                        missingNotesGV.DataSource = dt;

                        missingNotesGV.DataBind();

反向执行 for 循环很重要,否则如果您在删除末尾的行以及其他位置的行时会出错。

答案 9 :(得分:-1)

当我遇到这个问题时,我就这样做了。

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

答案 10 :(得分:-2)

试试这个

foreach(DataRow oRow in YourDataTable.Rows)
{
  if ("Check You Condition")
   {
      YourDataTable.Rows.Remove(oRow);
   }
}