Domanda

Non capisco perché questo codice non funziona.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}
È stato utile?

Soluzione

Anche se DataRow.Delete non modifica lo stato della raccolta, documentazione di Microsoft afferma che non si deve chiamare, mentre l'iterazione sulla raccolta:

  

Né Elimina né Rimuovere dovrebbe essere chiamato in un ciclo foreach, mentre l'iterazione attraverso un oggetto DataRowCollection. Eliminare né Rimuovere modificare lo stato della collezione.

La soluzione migliore è di solito per creare una raccolta differenziata (per esempio un List<DataRow>) di elementi che si desidera rimuovere, quindi rimuoverli dopo si iterazione hai finito.

Questa è anche la soluzione per le situazioni in cui si desidera rimuovere elementi da una collezione, come la maggior parte raccolte in .NET non consentono di modificare i contenuti della collezione, mentre si sta iterando su di esso.

Altri suggerimenti

modo più sicuro - uso ciclo for

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

Non dimenticare di AcceptChanges per rimuovere tutte le righe marcate:

datatable.AcceptChanges();

Non è possibile modificare una raccolta, mentre si sta iterando su di esso utilizzando una dichiarazione foreach.

si può provare qualcosa di simile:

List<DataRow> deletedRows = new List<DataRow>();

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

foreach(DataRow dataRow in deletedRows)
{
    dataRow.Delete();
}

Se si chiama il metodo di eliminazione è sufficiente chiamare AcceptChanges() sul tavolo si sta modificando, dopo il ciclo foreach.

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

dataTable.AcceptChanges();

Il metodo delete segna semplicemente la fila per l'eliminazione.

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

può essere la mia risposta non è più utile. eccezione tiro in Foreach con DataRow appaiono solo in .Net 2.0 e versioni precedenti, la ragione è la descrizione a MSDN http: // MSDN. microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx

Se la RowState della riga viene aggiunta, la riga viene rimossa dalla tabella.

Il RowState viene eliminato dopo aver utilizzato il metodo Delete. Rimane eliminati fino a quando si chiama AcceptChanges.

Una riga eliminata può essere eliminate invocando RejectChanges.

per passare questo problema è possibile chiamare DataTable.AcceptChanges () prima di utilizzare foreach

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

dataTable.AcceptChanges();

Si prega di fare riferimento gli snap per understatnd il funzionamento di esso.

  1. appena cancellato, ma non rimosso dal DataTable.

entrare descrizione dell'immagine qui

  1. Punto di rottura prima AcceptChanges () Funzione. entrare descrizione dell'immagine qui
  2. Dopo Eexecuting AcceptChanges () Funzione. entrare descrizione dell'immagine qui

Spero che questo problema è stato risolto ora.

Le modifiche al contenuto Rows mentre si è l'iterazione se si elimina una riga, che rende l'iterazione valido.

È possibile, tuttavia, copiare le righe in una collezione e poi iterare la raccolta e cancellare le righe in questo modo. Questo fa in modo che l'iterazione non è interrotto modificando dati da iterata.

Il modo più semplice per raggiungere questo obiettivo utilizzando un elenco per mappare le righe che si desidera eliminare e quindi eliminare le righe al di fuori iterazione 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

C'è un'altra versione di esso (credo uno più facile) quello che ho appena usato:

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

Questa veloce.

Solo per le persone che sono alla ricerca di scenario specifico, come me, Ho bisogno di abbreviare tempo impiegato, e una volta alcuni infomation utile viene estratto da ciascuna riga, ho escluso la riga contrassegnando come cancellata.

Spero che questo aiuto a qualcuno ...

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

Questo vale per praticamente qualsiasi collezione. Se si tenta di eliminare un elemento, mentre scorrendo la raccolta, si avrà un problema. Ad esempio, se si elimina riga # 3, quindi la precedente riga # 4 diventa riga # 3.

Quando gli oggetti hanno un Count, questo è quello che ho fatto:

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

Si noti che dove gli oggetti hanno una collezione .GetXXXX(), come FileInfo (IIRC), cancellazione del contenuto della voce in una foreach è accettabile. Una soluzione che ho considerato è creare un metodo di estensione che fornisce un metodo .GetItems().

Utilizzare questa:

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

{

 myDataTable[i].Delete();

}

Questo è perché sembra tentare di smontare la scala di scala che si sale. Semplicemente, non è possibile rimuovere un elemento di eseguire iterazioni.

Per questo è necessario utilizzare array diverso per scorrere e rimuoverli dalla proprietà Rows DataTable.

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

Certo magenti

Ecco come ho fatto e funziona benissimo

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++;        
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top