Überprüfen Sie, ob noch ausstehende Änderungen gespeichert werden müssen

75

Gibt es eine Möglichkeit, herauszufinden, ob es in meinem Entitätskontext im Entitätsframework nicht gespeicherte Änderungen gibt?

Palantir
quelle
Überprüft context.savechanges () dies nicht automatisch? Grund, if (db.ChangeTracker.HasChanges()) { await db.SaveChangesAsync(); }
warum

Antworten:

60

Dies könnte funktionieren (wenn Sie unter Änderungen das Hinzufügen, Entfernen und Ändern von Entitäten verstehen):

bool changesMade = (context.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Count() +
                    context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted).Count() +
                    context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified).Count()
                    ) > 0;

Bearbeiten:

Verbesserter Code:

bool changesMade = context.
                   ObjectStateManager.
                   GetObjectStateEntries(EntityState.Added | 
                                         EntityState.Deleted | 
                                         EntityState.Modified
                                        ).Any();
Yakimych
quelle
12
+1 für allgemein auf dem richtigen Weg, aber Any()nicht verwenden Count() > 0.
Craig Stuntz
Verdammt - lesen Sie noch heute Ihren Blogpost dazu! Danke;)
Yakimych
Beachten Sie, dass EF nicht prüft, ob der Wert (für EntityState.Modified) wirklich unterschiedlich ist . Wenn Sie einen Wert durch sich selbst ersetzen, gibt EF zurück 1 modified object. Sie müssen vorher prüfen, ob der Wert unterschiedlich ist.
Matthieu Charbonnier
100

Ab EF 6 gibt es context.ChangeTracker.HasChanges().

Thaoden
quelle
3
Die aktuellste Antwort.
Zapnologica
1
Ab 2016 ist dies die Antwort, IMHO.
Ozgur
Dies ist jetzt die beste Antwort, wie andere erwähnt haben.
Yokomoko
Ordentliche Lösung! Danke für das Teilen. Wissen Sie, wie Sie Änderungen rechtzeitig erfassen und das geänderte Formular mit "*" markieren können? wie: Form1 *
Rapunzo
42

Für diejenigen unter Ihnen, die EF 4+ verwenden, ist hier eine äquivalente Lösung als Erweiterungsmethode:

public static class DbContextExtensions {
    public static Boolean HasPendingChanges(this DbContext context) {
        return context.ChangeTracker.Entries()
                      .Any(e => e.State == EntityState.Added
                             || e.State == EntityState.Deleted
                             || e.State == EntityState.Modified);
    }
}

Beachten Sie, dass Sie die Werte nicht als Bitmaske kombinieren können. Die Funktion hat GetObjectStateEntries()die Logik für Sie übernommen, aber LINQ liefert keine korrekten Ergebnisse.

Yuck
quelle
4
Vielen Dank, die akzeptierte Antwort hat bei mir nicht funktioniert (EF v.4.3).
Christian
1
EntityStatedenn EntityState.Addedist von System.Data.Entityund nicht von System.Data.
Yuck