DataTable, cómo eliminar condicional filas

Estoy involucrado en un proceso de aprendizaje C # y va bien hasta ahora. Sin embargo, ahora mismo toco mi primer “¿decir qué?” momento.

DataTable ofrece acceso de fila aleatorio a su colección de Filas, no solo a través del comportamiento de las colecciones típicas, sino también a través de DataTable.Select. Sin embargo, parece que no puedo vincular esta capacidad con DataRow.Delete. Hasta ahora esto es lo que parece que necesito hacer para eliminar condicionalmente una o más filas de una tabla.

int max = someDataTable.Rows.Count - 1; for(int i = max; i >= 0; --i) { if((int)someDataTable.Rows[i].ItemArray[0] == someValue) { someDataTable.Rows[i].BeginEdit(); someDataTable.Rows[i].Delete(); } else break; } someDataTable.AcceptChanges(); 

Pero no estoy contento con este código. Ni estoy convencido. Debo estar perdiendo algo. ¿De verdad me veo obligado a presionar secuencialmente la colección Filas si necesito eliminar una o más filas de forma condicional?

(No importa el invertido para. Estoy eliminando desde el final de la tabla de datos. Así que está bien)

Puede consultar el conjunto de datos y luego recorrer las filas seleccionadas para establecerlas como eliminar.

 var rows = dt.Select("col1 > 5"); foreach (var row in rows) row.Delete(); 

… y también puedes crear algunos métodos de extensión para que sea más fácil …

 myTable.Delete("col1 > 5"); public static DataTable Delete(this DataTable table, string filter) { table.Select(filter).Delete(); return table; } public static void Delete(this IEnumerable rows) { foreach (var row in rows) row.Delete(); } 

Aquí hay una línea usando LINQ y evitando cualquier evaluación en tiempo de ejecución de cadenas seleccionadas:

 someDataTable.Rows.Cast().Where( r => r.ItemArray[0] == someValue).ToList().ForEach(r => r.Delete()); 

No tengo un cuadro de Windows a mano para intentar esto, pero creo que puedes usar un DataView y hacer algo como esto:

 DataView view = new DataView(ds.Tables["MyTable"]); view.RowFilter = "MyValue = 42"; // MyValue here is a column name // Delete these rows. foreach (DataRowView row in view) { row.Delete(); } 

Sin embargo, no he probado esto. Puede intentarlo.

Método de extensión basado en Linq

 public static void DeleteRows(this DataTable dt, Func predicate) { foreach (var row in dt.Rows.Cast().Where(predicate).ToList()) row.Delete(); } 

Luego usa:

 DataTable dt = GetSomeData(); dt.DeleteRows(r => r.Field("Amount") > 123.12 && r.Field("ABC") == "XYZ");