2010-05-26 20 views

Respuesta

49

Depende de lo que entendemos por 'eliminar'.

Si se refiere a los marcan como eliminado, simplemente llame al método Delete() en cada fila como lo visita en su bucle. Luego debe llamar al AcceptChanges() en la tabla de datos para finalizar la eliminación, presumiblemente después de actualizar su base de datos (si hay alguna involucrada).

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

Si se refiere a sacarlo de la DataTable, entonces usted necesita para hacerlo en dos pasos:

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

Vale la pena señalar que siempre se puede utilizar el primer método para eliminar filas - ya que marcar las filas como Deleted y aceptar cambios las eliminará automáticamente de la tabla. Pero, a veces es más claro y eficiente simplemente eliminar los objetos DataRow de la colección Rows.

+0

+1 por esta gran explicación, ¡era algo preocupante con esto! – Jithu

+4

Si hace lo mismo que lo que dijo LBushkin, verá lo siguiente: Se modificó la colección; la operación de enumeración podría no ejecutarse. así que está mal. – Szjdw

+1

Siempre que invoque .AcceptChanges() antes de marcar filas como eliminadas (antes del bucle foreach), no obtendrá el error "La colección se modificó; la operación de enumeración podría no ejecutarse". El error aparece porque hay cambios pendientes que deben aceptarse. Si usa un bucle for, entonces no importará, pero en ese caso sería mejor iterar hacia atrás. – Soenhay

8

Pruebe algo como este ejemplo

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 para el revés iteración para mantener índices del – riffnl

+0

También se podría hacer un bucle hacia delante (0 -> Count-1) si se mueve la 'i ++' dentro del bucle y sólo de la subasta cuando no borrar . 'if (...) remove() else i ++' – CuppM

0

intente iterar sobre el resultado de Seleccionar(). Esto es bastante similar a otras respuestas, pero me parece que es la más directa

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

prueba este

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

No puede modificar una colección mientras itera a través de ella con un bucle foreach. –

4

La otra forma es

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

Ésta es la forma en que lo hice cuando me encontré con este problema.

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

Siempre he utilizado el enfoque "en dos fases" de LBushkin y finalmente decidí que valía la pena escribir una función para ello:

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

Y ahora puedo eliminar filas con una sola línea de código (por ejemplo):

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

En caso de que esto ayude a ...

(y cualquier forma de furthe r abreviar son apreciadas.)

4

Si desea una solución más corto que los propuestos anteriormente, trata de bucle sobre la lista de resultados, y usando un lambda como sub(x) para eliminar cada una de esas filas.

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

Para eliminar varias filas (por ejemplo, 50.000 de cada 100.000) es mucho más rápido para copiar la base de datos que hay que hacer, ya sea datatable.Rows.Remove (fila) o row.Delete(). Por ejemplo:

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