Wie kann man Entity Framework zwingen, immer aktualisierte Daten aus der Datenbank abzurufen?

85

Ich verwende die EntityFramework.Extended- Bibliothek, um Stapelaktualisierungen durchzuführen. Das einzige Problem ist, dass EF die von der Bibliothek durchgeführten Stapelaktualisierungen nicht verfolgt. Wenn ich das DbContexterneut abfrage, werden die aktualisierten Entitäten nicht zurückgegeben.

Ich habe festgestellt, dass die Verwendung der AsNoTracking()Methode beim Abfragen das Tracking deaktiviert und frische Daten aus der Datenbank abruft. Da EF jedoch die abgefragten Entitäten nicht verfolgt, kann AsNoTracking()ich keine Aktualisierung der abgefragten Daten durchführen.

Gibt es eine Möglichkeit, EF zu zwingen, die neuesten Daten abzurufen, während Änderungen verfolgt werden?

Saravana
quelle
2
29k Aufrufe und nur 19 Upvotes dazu ... nun, ich habe meine trotzdem hinzugefügt
jleach

Antworten:

146

Bitte versuchen Sie dies, um eine einzelne Entität zu aktualisieren:

Context.Entry<T>(entity).Reload()

Bearbeiten: Um neue Daten für eine Sammlung von Entitäten zu erhalten, sollten Sie versuchen, die DbContextInstanz nach jeder Anforderung zu entsorgen .

PlTaylor
quelle
Vielen Dank! Gibt es eine Möglichkeit, eine Sammlung von Entitäten neu zu laden, anstatt eine? Am liebsten das ganze DbSet.
Saravana
Gibt es noch etwas, das Sie benötigen, um als Antwort zu gelten?
PlTaylor
1
Ja, es wird immer noch nicht angezeigt, wie eine Sammlung von Entitäten neu geladen wird.
Saravana
1
Haben Sie versucht, Ihren Datenbankkontext zu entsorgen und einen neuen zu erstellen?
PlTaylor
2
Ich habe Stunden gebraucht, um zu diesem Schluss zu kommen. Diese BEARBEITUNG in der Antwort hat mir geholfen, meine Lösung zu finden. Vielen Dank!
BeemerGuy
17

Ich bin auf diese Frage gestoßen, als ich nach einer Lösung für ein Problem gesucht habe, bei dem die Navigationseigenschaften nach dem Aktualisieren der Entität nicht ausgefüllt wurden. Immer wenn ich versuchte, die Entität aus der Datenbank neu zu laden, wurde stattdessen der Eintrag aus dem lokalen Speicher abgerufen, wodurch die Navigationseigenschaften nicht durch verzögertes Laden aufgefüllt wurden. Anstatt den Kontext zu zerstören und einen neu zu erstellen, konnte ich auf diese Weise neue Daten mit den funktionierenden Proxys abrufen:

_db.Entry(entity).State = EntityState.Detached;

Die Logik dahinter war - mein Update hat die Entität angehängt, damit Änderungen daran nachverfolgt werden können. Dies fügt es dem lokalen Geschäft hinzu. Danach würde jeder Versuch, die Entität mit funktionalen Proxys abzurufen, dazu führen, dass sie die lokale Entität greift, anstatt zur Datenbank zu gehen und eine neue, Proxy-fähige Entität zurückzugeben. Ich habe oben die Option zum erneuten Laden ausprobiert, mit der das Objekt aus der Datenbank aktualisiert wird. Das Proxy-Objekt wird jedoch nicht verzögert geladen. Ich habe versucht, eine Find(id), Where(t => t.Id = id), First(t => t.Id = id). Schließlich überprüfte ich die verfügbaren Zustände, die bereitgestellt wurden, und stellte fest, dass es einen "getrennten" Zustand gab. Eureka! Hoffe das hilft jemandem.

Zach
quelle
Wo wenden Sie den Status "Freistehend" an, damit das verzögerte Laden funktioniert? Ich habe Ihre Lösung ausprobiert und es hat bei mir nicht funktioniert, ich muss etwas verpassen. Ihre Hilfe wäre dankbar
Rex
2
Ich habe es herausgefunden: 1. Speichern Sie die Entität, 2. Setzen Sie den Status auf Trennen, 3. Lesen Sie die Entität aus der Datenbank. Danke für den Tipp!
Rex
1

Wenn Sie den Code im selben Kontext ausführen, erhalten Sie keine aktualisierten Entitäten. Es werden nur neue Entitäten angehängt, die zwischen den Läufen in der Datenbank erstellt wurden. EF Force Reload kann folgendermaßen durchgeführt werden:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();
CodeMad
quelle
1

Ich habe die Entitätsvariable ohne Zuweisung als Teil der Klasse deklariert. Dadurch konnte ich eine Instanz entsorgen, ohne die Variable als Referenz für andere Methoden zu verlieren. Ich bin gerade darauf gestoßen, damit es nicht viel Laufzeit gibt, aber bisher scheint es gut zu funktionieren.

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}
Roller
quelle
0

Für mich ... Ich greife wie folgt auf meinen DbContext zu:

_viewModel.Repo.Context

Um EF zu zwingen, auf die Datenbank zuzugreifen, gehe ich folgendermaßen vor:

_viewModel.Repo.Context = new NewDispatchContext();

Überschreiben des aktuellen DbContext mit einer neuen Instanz. Wenn ich dann das nächste Mal meine Datendienste benutze, erhalten sie die Daten aus der Datenbank.

pdschuller
quelle