Ich sehe hier verschiedene Teile der richtigen Antwort, aber lassen Sie mich alles zusammenbringen und ein paar Dinge erklären.
Zunächst AcceptChanges
sollte nur verwendet werden, um die gesamte Transaktion in einer Tabelle als validiert und festgeschrieben zu markieren. Wenn Sie also die DataTable als DataSource zum Binden an beispielsweise einen SQL Server verwenden, wird durch AcceptChanges
manuelles Aufrufen sichergestellt, dass die Änderungen niemals auf dem SQL Server gespeichert werden .
Was dieses Problem verwirrender macht, ist, dass es tatsächlich zwei Fälle gibt, in denen die Ausnahme ausgelöst wird und wir beide verhindern müssen.
1. Ändern der Sammlung eines IEnumerable
Wir können der Aufzählung keinen Index hinzufügen oder entfernen, da dies die interne Indizierung des Enumerators beeinträchtigen kann. Es gibt zwei Möglichkeiten, dies zu umgehen: Führen Sie entweder Ihre eigene Indizierung in einer for-Schleife durch oder verwenden Sie eine separate Sammlung (die nicht geändert wird) für die Aufzählung.
2. Versuch, einen gelöschten Eintrag zu lesen
Da es sich bei DataTables um Transaktionssammlungen handelt , können Einträge zum Löschen markiert werden, erscheinen jedoch weiterhin in der Aufzählung. Das heißt, wenn Sie einen gelöschten Eintrag für die Spalte "name"
anfordern, wird eine Ausnahme ausgelöst. Das heißt, wir müssen prüfen, ob, dr.RowState != DataRowState.Deleted
bevor wir eine Spalte abfragen.
Alles zusammenfügen
Wir könnten chaotisch werden und all das manuell erledigen, oder wir könnten die DataTable die ganze Arbeit für uns erledigen lassen und die Anweisung wie einen SQL-Aufruf aussehen lassen, indem wir Folgendes tun:
string name = "Joe";
foreach(DataRow dr in dtPerson.Select($"name='{name}'"))
dr.Delete();
Durch den Aufruf der DataTable- Select
Funktion vermeidet unsere Abfrage automatisch bereits gelöschte Einträge in der DataTable. Und da die Select
Funktion ein Array von Übereinstimmungen zurückgibt, wird die Sammlung, über die wir aufzählen, beim Aufruf nicht geändert dr.Delete()
. Ich habe auch den Select-Ausdruck mit String-Interpolation aufgepeppt, um eine Variablenauswahl zu ermöglichen, ohne den Code verrauschen zu lassen.
[ii]
zu[i]
:-)