如何删除DataTable中的多行?

发布于 2024-09-03 17:27:22 字数 79 浏览 4 评论 0原文

如何删除符合自定义条件的 DataTable 行循环中的特定 DataRow(假设索引为偶数的行)? (不使用 LINQ)

谢谢

How can I delete specific DataRows within a loop of a DataTable rows which meet a custom condition -lets say the rows having an index of even number-? (Without using LINQ)

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

清风疏影 2024-09-10 17:27:22

这取决于您所说的“删除”的含义。

如果您的意思是将它们标记为已删除,只需在每一行上调用 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 然后接受更改会自动将其从表中删除。但是,有时从 Rows 集合中删除 DataRow 对象会更清晰、更高效。

It depends on what you mean by 'delete'.

If you mean mark them as deleted, just call the Delete() method on each row as you visit it in your loop. You then need to call AcceptChanges() on the data table to finalize the delete - presumably after you update your database (if one is involved).

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

If you mean remove it from the DataTable, then you need to do so in two passes:

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

It's worth pointing out that you can always use the first method to remove rows - since marking rows as Deleted and then accepting changes will automatically remove them from the table. But, sometimes it is more clear and efficient to simply remove the DataRow objects from the Rows collection.

调妓 2024-09-10 17:27:22

尝试类似这个例子的东西

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

Try something like this example

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);
}
↘紸啶 2024-09-10 17:27:22

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

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

If you want a shorter solution than those proposed above, try looping over the list of results, and using a lambda like sub(x) to remove each of those rows.

dt.Select("Column1 > 0").ToList.ForEach(Sub(x) dt.Rows.Remove(x))
影子是时光的心 2024-09-10 17:27:22

另一种方法是

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

The other way is

    DataRow[] DrArrCheck = DataTableName.Select("ID > 0");
    foreach(DataRow DrCheck in DrArrCheck)
    {
        DataTableName.Rows.Remove(DrCheck);
    }
冷血 2024-09-10 17:27:22

要删除多行(例如 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();

To delete multiple rows (for instance 50,000 out of 100,000) it is much quicker to copy the database than to do either datatable.Rows.Remove(row) or row.Delete(). For instance:

DataRow[] rowsToKeep = datatable.Select("ID > 50000");
DataTable tempDataTable= rowsToKeep.CopyToDataTable;
dataTable.Clear();
dataTable.Merge(tempDataTable);
tempDataTable.Dispose();
金兰素衣 2024-09-10 17:27:22
 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);
        }
 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);
        }
萌梦深 2024-09-10 17:27:22

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

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

try iterating over the result of Select(). This is pretty similar to other answers, but I find it the most direct

DataRow[] r = table.Select();
for (int i = 0; i < r.Length; i++)
{
    if (i % 2 == 0)
        r[i].Delete();
}
离去的眼神 2024-09-10 17:27:22

我总是使用 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);

万一这对任何人有帮助......

(任何进一步缩写的方法都值得赞赏。)

I always used LBushkin's "two-phase" approach and I finally decided it was worth it to write a function for it:

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

And now I can delete rows with one line of code (for example):

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

In case this helps anyone...

(And any ways to further abbreviate are appreciated.)

作妖 2024-09-10 17:27:22

我就是这样做的。

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

                        missingNotesGV.DataSource = dt;

                        missingNotesGV.DataBind();

反向执行 for 循环很重要,否则如果除了其他位置的行之外还删除末尾的行,则会出现错误。

This is how I do it.

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

                        missingNotesGV.DataSource = dt;

                        missingNotesGV.DataBind();

Its important to do the for loop in reverse otherwise you get errors if you're removing rows at the end in addition to rows in other places.

狼亦尘 2024-09-10 17:27:22

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

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

This is how I did it when I ran into this issue.

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
笑红尘 2024-09-10 17:27:22

试试这个

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

try this

foreach(DataRow oRow in YourDataTable.Rows)
{
  if ("Check You Condition")
   {
      YourDataTable.Rows.Remove(oRow);
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文