2010-05-26 84 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();