Deaktivieren / Deaktivieren des Entity Framework-Cache

8

Ich sehe, es gibt viele Fragen zum EF-Cache, aber ich habe noch keine Lösung für mein Problem gefunden.

Die direkte Frage ist

Wie deaktiviere ich den Cache von Entity Framework 6 vollständig? Oder kann ich EF programmatisch mitteilen, den Cache zu vergessen, weil etwas mit Daten passiert ist?

Hintergrund

Zuerst habe ich geerbt eine Anwendung, die aus einer seltsamen Mischung von EF (Modell - zuerst zum Definieren von Entitäten) und einfachem altem SQL (zum Manipulieren von Daten) gemacht wurde. Ich habe die Anwendung umgestaltet, um:

  • Einfache Abfragen (wie GetAll() für eine Entität) verwenden EF6 LINQ
  • Lassen Sie komplexe Datenmanipulation in SQL mit DbContext.Database.Connection bei Bedarf
  • Fügen Sie Spring.Web support hinzu, um DI und Transaktionen (noch nicht) zu aktivieren

An der aktuellen Stelle habe ich den Code so reorganisiert, dass die Hauptfunktion der Anwendung (komplexe SQL-Abfragen in riesigen Datenmengen) wie zuvor funktioniert, aber die Manipulation der Domänenmanipulation mit Hilfe von als smarter durchgeführt wird das meiste Entity Framework als möglich

Wie die meisten ....

Eine der Seiten, die ich geerbt habe, ist eine Multi-Checkbox-Seite, die ich Ihnen zum besseren Verständnis zeigen werde. Ich werde nicht auf die Wahl des vorherigen Implementers eingehen, da es billiger ist, mein aktuelles Problem zu beheben und den Code später zu refaktorisieren, als die Entwicklung für ein defektes Feature zu blockieren.

So sieht die Seite aus

Grundsätzlich ist die Methode Controller die folgende

%Vor%

Jeder Parameter string[] ist eine Spalte in der Tabelle. Die Methode ActivateFlagFor führt zwei Abfragen nacheinander aus

%Vor%

Wenn der Cache eintritt

Folgendes ist das Verhalten:

  • Zuerst lade ich die Seite, die LINQ ausgibt. select: checks stimmen mit den Einsen und Nullen in den Spalten
  • überein
  • Ich ändere eine oder mehrere Prüfungen und reiche
  • ein
  • Der Controller gibt die Abfragen aus, um die Prüfungen im DB zu aktualisieren
  • Vor dem Weiterleiten (! bedeutet eine neue Anfrage!), um die Seite neu zu laden, überprüfe ich die DB und die Änderungen werden angewendet
  • Die Seite wird neu geladen und gibt die gleiche LINQ aus wie oben angegeben: alte Prüfungen werden angezeigt

Ich bin mir sicher, dass dies ein Caching-Problem ist, da das erneute Laden der Anwendung das Problem behebt. Da das Hauptmerkmal der Anwendung vollständig auf SQL basiert, werden Änderungen an Nachschlagetabellen in die Hauptoperation übernommen und das ist das richtige Verhalten.

Ich verstehe, dass das EF-Caching ein großartiges Feature für die Performance ist, aber in meinem Fall möchte ich es einfach nicht, zumindest bis ich die gesamte Anwendung auf LINQ DML migrieren kann (wahrscheinlich unmöglich).

Wie benutze ich DbContext

Natürlich werden einige von Ihnen fragen: "Wie verwenden Sie Ihren DbContext?" "Verfügen Sie darüber richtig?".

  • Ich habe Spring-Transaktionen in meinen Manager-Klassen noch nicht integriert
  • Jedes Objekt, das Aktionen in der Datenbank ausführt, ist ein I<Entity>Manager extending BaseManager
  • DbContext ist ein Anforderungsbereichs-Spring-Objekt. Ich habe bereits gefragt, ob Objekte mit Anforderungsbereichen verfügbar sind , aber ich habe derzeit eine Problemumgehung implementiert, die zwar schlecht ist, entledigt sich am Ende der Anfrage korrekt dem DbContext.

Beispielcode

%Vor%

und

%Vor%

Was ich versucht habe

usr-local-ΕΨΗΕΛΩΝ 30.01.2015, 10:03
quelle

2 Antworten

19

Wenn Sie den Cache von EF6 für den Datenabruf vollständig ignorieren möchten, fügen Sie am Ende Ihrer Abfrage AsNoTracking() hinzu (bevor Sie ToList() aufrufen oder irgendetwas anderes ausführen, das die Abfrage ausführen würde.)

MSDN auf AsNoTracking()

Beachten Sie, dass dabei weder der Cache nach vorhandenen Daten überprüft noch die Ergebnisse des Datenbankaufrufs dem Cache hinzugefügt werden. Darüber hinaus erkennt Entity Framework Änderungen an Entitäten, die Sie aus der Datenbank abrufen, nicht automatisch. Wenn Sie Entitäten ändern und sie in der Datenbank speichern möchten, müssen Sie die geänderten Entitäten anhängen, bevor Sie SaveChanges() aufrufen.

Ihre Methode ist momentan:

%Vor%

Es würde sich ändern zu:

%Vor%

Wenn Sie an anderen Optionen zum Umgang mit dem Cache von EF interessiert sind, habe ich eine geschrieben Blogpost über EF6 Cache Busting .

    
CodeThug 22.02.2016, 03:24
quelle
3

Ich hatte auch diese Probleme, aber ich konnte es beheben.

Ich verwende das Repository-Muster und verwende die Standard-DI von .Net Core. Ich habe AddSingleton (...) verwendet, aber es ist falsch, mit DbContext zu verwenden.

Also habe ich zu AddScoped gewechselt, wie ich es aus der Dokumentation gelesen habe: Scoped Lifetime Services werden einmal pro Anfrage erstellt.

Es hat mein Problem gelöst.

Sie müssen diesen Abschnitt von ms lesen Dokumente: Service-Lebenszeiten und Registrierungsoptionen

    
Alef Carlos 08.01.2017 14:30
quelle

Tags und Links