De Forma Segura La Eliminación De DataRow En ForEach
-
22-09-2019 - |
Pregunta
No entiendo por qué este código no funciona.
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
Solución
A pesar de que DataRow.Delete
no modifica el estado de la colección, documentación de Microsoft estados que no se debe llamar al iterar sobre la colección:
Ni Delete ni Remove debe ser llamado en un bucle foreach mientras iteración a través de un objeto DataRowCollection. Eliminar ni modificar Retire el estado de la colección.
La mejor solución es por lo general para crear una colección separada (por ejemplo, un List<DataRow>
) de elementos que desea eliminar y, a continuación, eliminarlos después que haya terminado la iteración.
Esta es también la solución para las situaciones en las que desee eliminar elementos de una colección, como la mayoría de las colecciones en .NET no permiten cambiar el contenido de la colección mientras se está interactuando sobre ella.
Otros consejos
forma más segura - bucle uso for
for (int i = datatable.Rows.Count - 1; i >= 0; i--)
{
if (true)
{
datatable.Rows[i].Delete();
}
}
No se olvide de AcceptChanges
para eliminar todas las filas marcadas:
datatable.AcceptChanges();
No se puede modificar una colección mientras estás iterando sobre el mismo mediante una instrucción foreach
.
puede intentar algo así:
List<DataRow> deletedRows = new List<DataRow>();
foreach (DataRow dataRow in dataTable.Rows)
{
if(true) deletedRows.Add(dataRow);
}
foreach(DataRow dataRow in deletedRows)
{
dataRow.Delete();
}
Si se llama al método de eliminación sólo hay que llamar AcceptChanges()
en la tabla que se está modificando, después de que el bucle foreach.
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
dataTable.AcceptChanges();
El método Delete simplemente marca la fila para su eliminación.
http: //msdn.microsoft.com/en-us/library/system.data.datarow.delete%28v=VS.90%29.aspx
puede ser mi respuesta no útil más larga. tiro excepción en Foreach con DataRow sólo aparecen en .Net 2.0 y anteriores, la razón es la descripción en MSDN http: // MSDN. microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx
Si el RowState de la fila se añade, la fila se elimina de la tabla.
El RowState convierte eliminados después de utilizar el método Delete. Sigue siendo eliminados hasta que llame AcceptChanges.
Una fila pueden recuperarse mediante la invocación de RejectChanges suprimirse.
para pasar a este problema, puede llamar DataTable.AcceptChanges () antes de usar foreach
foreach (DataRow dataRow in dataTable.Rows)
{
if (true)
{
dataRow.Delete();
}
}
dataTable.AcceptChanges();
Por favor, consulte los broches de presión a understatnd el funcionamiento de la misma.
- acaba de eliminar, pero no retirado de la DataTable.
- Salto de punto antes de AcceptChanges () función.
- Después de Eexecuting AcceptChanges () función.
Espero que este problema resuelto ahora.
El contenido Rows
cambia mientras está iteración si elimina una fila, lo que hace que el enfermo iteración.
Puede, sin embargo, copiar las filas en una colección primero y luego iterar sobre la colección y eliminar las filas de esa manera. Esto asegura que la iteración no se interrumpe al cambiar los datos a ser iterado.
La forma más sencilla de lograr esto mediante el uso de una lista para asignar filas que desea eliminar y luego Eliminar filas fuera iteración DataTable.
C #
List<DataRow> rowsWantToDelete= new List<DataRow>();
foreach (DataRow dr in dt.Rows)
{
if(/*Your condition*/)
{
rowsWantToDelete.Add(dr);
}
}
foreach(DataRow dr in rowsWantToDelete)
{
dt.Rows.Remove(dr);
}
VB
Dim rowsWantToDelete As New List(Of DataRow)
For Each dr As DataRow In dt
If 'Your condition' Then
rowsWantToDelete .Add(dr)
End If
Next
For Each dr As DataRow In rowsWantToDelete
dt.Rows.Remove(dr)
Next
Hay una otra versión de la misma (creo que una más fácil) lo que acabo de utilizar:
int i=0;
while (i < myDataTable.Rows.Count)
{
if (condition) //should it be deleted?
myDataTable.Rows.RemoveAt(i);
else
i++;
}
Este rápido.
Sólo para personas que están buscando para la situación específica en la que como yo, Yo necesitaba para acortar tiempo, y una vez que útil la información se extrae de cada fila, yo excluidos de la hilera marcado como eliminado.
Espero que esto ayude a alguien...
foreach (DataRow dataRow in dataTable.Rows)
{
if (dataRow.RowState != DataRowState.Deleted)
{
if (your condition here)
{
dataRow.Delete();
}
}
}
Esto se aplica a casi cualquier colección. Si intenta eliminar un elemento, mientras que bucle a través de la colección, tendrá un problema. Por ejemplo, si la fila de borrar # 3, a continuación, la fila anterior # 4 se convierte en fila # 3.
Cuando los elementos tienen un Count
, esto es lo que he hecho:
int Count = myTable.Rows.Count;
while (Count > 0) // replace condition with myTable.Rows.Count if unconditionally performed on all rows
{
DataRow row = myTable.Rows[0] // or however you want to find your index
// do some work
myTable.Rows.Remove(row);
// if you want to perform a check to break out of while
if (someCondition)
Count = 0;
else
Count = myTable.Rows.Count;
}
Tenga en cuenta, que cuando los objetos tienen una colección .GetXXXX()
, como FileInfo
(IIRC),
borrado de los contenidos de elementos en un foreach
es aceptable. Una solución que he considerado es la creación de un método de extensión que proporciona un método .GetItems()
.
Utilice esta:
for (int i = 0; i < myDataTable.Rows.Count; i++)
{
myDataTable[i].Delete();
}
Esto es porque parece que intente desmontar la escalera de la escalera que se pueda subir. Simplemente, no se puede eliminar un elemento iterar.
Por lo tanto usted debe utilizar diferentes matriz para iterar y sacarlos de la propiedad Rows
tabla de datos.
foreach (DataRow dataRow in dataTable.Select())
{
if (true)
{
dataTable.Rows.Remove(dataRow);
}
}
seguro de Magents
Esto es cómo lo hice y funciona bien
dt = GetStationeryConsolidationDetails(txtRefNo.Text);
int intRows = dt.Rows.Count;
int x = 0;
for (int c = 0; c < intRows; c++)
{
if (dt.Rows[c - x]["DQTY"].ToString() == "0")
{
dt.Rows[c - x].Delete();
dt.AcceptChanges();
x++;
}
}