2010-05-26 99 views

回答

49

这取决于你的意思是 '删除' 的东西。

如果你的意思是它们标记为删除,只需拨打各行上Delete()方法,你在你的循环访问它。然后,您需要在数据表上调用AcceptChanges()来完成删除 - 大概在您更新数据库(如果有人参与)之后。

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

如果你的意思是从数据表中删除它,那么你需要在两道这样做:

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对象就会更加清晰高效。

+0

+1这个很好的解释,让我担心这个! – Jithu 2011-12-26 13:59:08

+4

如果您按照LBushkin的说法做同样的事情,您会看到如下内容: 收藏已被修改;枚举操作可能不会执行。 所以这是错误的。 – Szjdw 2013-01-25 12:48:44

+1

只要您在将行标记为已删除之前调用.AcceptChanges()(在foreach循环之前),您将不会收到“集合被修改;枚举操作可能不会执行”的错误。出现该错误的原因是存在需要接受的待处理更改。如果你使用for循环,那么它并不重要,但在这种情况下,最好是向后迭代。 – Soenhay 2013-05-22 19:48:37

8

尝试是这样的例子

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

+1的向后迭代,以保持indicies – riffnl 2010-05-26 13:30:11

+0

也可以做一个正向循环(0 - >计数-1),如果您将'我++'里面的for循环,只有增量时不删除。 'if(...)remove()else i ++' – CuppM 2010-05-26 14:14:16

0

尝试迭代Select()的结果。这是非常类似于其他的答案,但我觉得它最直接的

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

试试这个

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

使用foreach循环遍历它时,您无法修改集合。 – 2012-01-18 16:57:11

4

另一种方式是

DataRow[] DrArrCheck = DataTableName.Select("ID > 0"); 
    foreach(DataRow DrCheck in DrArrCheck) 
    { 
     DataTableName.Rows.Remove(DrCheck); 
    } 
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); 
     } 
-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 
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); 

在此情况下,任何人都可以帮助...

(和任何方式来furthe [R缩写是赞赏。)

4

如果你想比上面提出的解决方案更短,尝试遍历结果列表,并使用拉姆达sub(x)删除这些每行。

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

要删除多行(例如50000出100,000)是能更快地复制,而不是做任何datatable.Rows.Remove(行)或row.Delete数据库()。例如:

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