Question

Je ne comprends pas pourquoi ce code ne fonctionne pas.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}
Était-ce utile?

La solution

Même si DataRow.Delete ne modifie pas l'état de la collection, documentation Microsoft indique que vous ne devriez pas l'appeler en itérer sur la collection:

  

Ni Supprimer ni les supprimer doit être appelé dans une boucle foreach tout itérer un objet DataRowCollection. Supprimer ni supprimer modifier l'état de la collection.

La meilleure solution est généralement de créer une collection séparée (par exemple un List<DataRow>) d'articles que vous voulez supprimer, puis les enlever après vous avez terminé itérer.

Ceci est également la solution pour les situations où vous voulez supprimer des éléments d'une collection, comme la plupart des collections .NET ne vous permettent pas de modifier le contenu de la collection pendant que nous parcourons dessus.

Autres conseils

plus sûr - l'utilisation de la boucle for

for (int i = datatable.Rows.Count - 1; i >= 0; i--) 
{
    if (true)
    {
        datatable.Rows[i].Delete();
    }
}

Ne pas oublier de AcceptChanges pour supprimer toutes les lignes marquées:

datatable.AcceptChanges();

Vous ne pouvez pas modifier une collection alors que nous parcourons à ce sujet en utilisant une instruction foreach.

vous pouvez essayer quelque chose comme ça:

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 vous appelez la méthode de suppression vous suffit d'appeler AcceptChanges() sur la table que vous modifiez, après la boucle foreach.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}

dataTable.AcceptChanges();

La méthode de suppression marque simplement la ligne pour la suppression.

http: //msdn.microsoft.com/en-us/library/system.data.datarow.delete%28v=VS.90%29.aspx

peut-être ma réponse ne sont plus utiles. jet d'exception dans le foreach avec DataRow apparaissent uniquement dans .Net 2.0 et plus tôt, la raison est la description à msdn http: // msdn. microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx

Si la RowState de la ligne est ajoutée, la ligne est retirée de la table.

Le RowState devient supprimé après avoir utilisé la méthode Delete. Il reste supprimé jusqu'à ce que vous appelez AcceptChanges.

Une ligne supprimée peuvent être rétablies en invoquant RejectChanges.

pour passer ce problème, vous pouvez appeler DataTable.AcceptChanges () avant d'utiliser foreach

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}

dataTable.AcceptChanges();

S'il vous plaît Reportez-vous les boutons-pression à understatnd le fonctionnement de celui-ci.

  1. Juste supprimé, mais pas retiré du DataTable.

entrer image description ici

  1. point de rupture avant AcceptChanges () Fonction. entrer image description ici
  2. Après Eexecuting AcceptChanges () Fonction. entrer image description ici

J'espère que ce problème résolu maintenant.

Les changements de contenu Rows pendant que vous itérez si vous supprimez une ligne, ce qui rend l'itération non valide.

Vous pouvez cependant copier les lignes dans une collection première et itérer puis sur la collecte et supprimer les lignes de cette façon. Cela fait en sorte que l'itération ne soit pas interrompue en changeant les données à itéré.

La meilleure façon d'y parvenir en utilisant une liste carte lignes que vous souhaitez supprimer, puis supprimer des lignes en dehors itération 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

Il y a une autre version (je pense un plus facile) ce que je viens d'utiliser:

int i=0;
while (i < myDataTable.Rows.Count)
{
    if (condition)  //should it be deleted?
        myDataTable.Rows.RemoveAt(i);
    else
        i++;
}

Cette plus rapide.

Seulement pour les personnes qui sont à la recherche pour le scénario spécifique comme moi, Je besoin de raccourcir le temps de prise, et une fois que certains infomation utile est extrait de chaque rangée, la rangée I exclu par le marquage comme supprimé.

Hope this quelqu'un aide ...

foreach (DataRow dataRow in dataTable.Rows)
{
    if (dataRow.RowState != DataRowState.Deleted)
    {
        if (your condition here)
        {
            dataRow.Delete();
        }
    }
}

Cela vaut pour à peu près toute collection. Si vous essayez de supprimer un élément en boucle à travers la collection, vous aurez un problème. Par exemple, si vous supprimez la ligne n ° 3, puis la ligne précédente # 4 est la ligne n ° 3.

Lorsque des éléments ont une Count, voici ce que je l'ai fait:

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

Notez que lorsque les objets ont une collection de .GetXXXX(), comme FileInfo (IIRC), la suppression du contenu de l'élément dans un foreach est acceptable. Une solution que je l'ai considéré est la création d'une méthode d'extension qui fournit une méthode de .GetItems().

Utilisez ceci:

for (int i = 0; i < myDataTable.Rows.Count; i++)

{

 myDataTable[i].Delete();

}

Ceci est parce qu'il ressemble à essayer de démonter l'escalier d'escalier que vous montez. Simplement, vous ne pouvez pas supprimer un élément que vous itérer.

Par conséquent, vous devez utiliser le tableau différent pour itérer et les retirer de la propriété DataTable Rows.

foreach (DataRow dataRow in dataTable.Select())
{
    if (true)
    {
        dataTable.Rows.Remove(dataRow);
    }
}

Bien sûr magents

Voici comment je l'ai fait et fonctionne très 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++;        
  }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top