Wenn Sie über dynamische Proxys in EF sprechen, müssen zwei verschiedene Typen unterschieden werden:
- Proxies für faules Laden
- Proxies für die Änderungsverfolgung
Normalerweise kann ein Änderungsverfolgungs-Proxy auch als Proxy für das verzögerte Laden dienen. Das Gegenteil ist nicht der Fall. Dies liegt daran, dass die Anforderungen an Änderungsverfolgungs-Proxys höher sind, insbesondere müssen alle Eigenschaften - auch die skalaren Eigenschaften - erfüllt sein virtual
. Für ein verzögertes Laden reichen die Navigationseigenschaften aus virtual
.
Die Tatsache, dass ein Änderungsverfolgungs-Proxy immer auch das verzögerte Laden ermöglicht, ist der Hauptgrund, warum der DbContext dieses Konfigurationsflag hat:
DbContext.Configuration.LazyLoadingEnabled
Dieses Flag ist standardmäßig wahr. Wenn Sie diese false
Option so einstellen , dass das verzögerte Laden deaktiviert wird, auch wenn Proxys erstellt werden. Dies ist besonders wichtig, wenn Sie mit Change-Tracking-Proxys arbeiten, diese Proxys jedoch nicht auch zum verzögerten Laden verwenden möchten.
Die Option ...
DbContext.Configuration.ProxyCreationEnabled
... deaktiviert die Proxy-Erstellung vollständig - auch für Änderungsverfolgung und verzögertes Laden.
Beide Flags haben nur dann eine Bedeutung, wenn Ihre Entitätsklassen die Anforderungen zum Erstellen von Änderungsverfolgungs- oder verzögerten Ladeproxys erfüllen.
Jetzt kennen Sie den Zweck des dynamischen verzögerten Ladens von Proxys. Warum sollte man also dynamische Änderungsverfolgungs-Proxys verwenden?
Der einzige Grund, den ich kenne, ist die Leistung . Dies ist jedoch ein sehr starker Grund. Beim Vergleich der auf Schnappschüssen basierenden Änderungsverfolgung mit der auf Proxys basierenden Änderungsverfolgung ist der Leistungsunterschied enorm - nach meinen Messungen ist ein Faktor von 50 bis 100 realistisch (entnommen aus einer Methode, die für 10000 Entites mit einer auf Schnappschüssen basierenden Änderungsverfolgung und 30 bis 60 Sekunden etwa eine Stunde benötigte nachdem alle Eigenschaften virtuell gemacht wurden, um Änderungsverfolgungs-Proxys zu aktivieren). Dies ist ein wichtiger Faktor, wenn Sie eine Anwendung haben, die viele (z. B. mehr als 1000) Entitäten verarbeitet und ändert. In einer Webanwendung, in der Sie möglicherweise nur Operationen zum Erstellen / Ändern / Löschen einzelner Entitäten in einer Webanforderung ausführen, ist dieser Unterschied nicht so wichtig.
In fast allen Situationen können Sie eifriges oder explizites Laden nutzen, um dasselbe Ziel zu erreichen, wenn Sie nicht mit Proxys zum verzögerten Laden arbeiten möchten. Die Leistung beim Proxy-basierten verzögerten Laden oder beim nicht-Proxy-basierten expliziten Laden ist dieselbe, da beim Laden der Navigationseigenschaften im Grunde dieselbe Abfrage erfolgt - im ersten Fall führt der Proxy die Abfrage durch, im zweiten Fall Ihren handgeschriebenen Code. Sie können also ohne verzögertes Laden von Proxys leben, ohne zu viel zu verlieren.
Wenn Sie jedoch eine angemessene Leistung für die Verarbeitung vieler, vieler Entitäten wünschen, gibt es keine Alternative zum Ändern von Tracking-Proxys - abgesehen von der Verwendung EntityObject
abgeleiteter Entitäten in EF 4.0 (keine Option in EF 4.1, da dies bei Verwendung verboten ist DbContext
) oder der Verwendung von Entity Framework überhaupt nicht .
Bearbeiten (Mai 2012)
In der Zwischenzeit habe ich erfahren, dass es Situationen gibt, in denen Change-Tracking-Proxys im Vergleich zu Snapshot-basiertem Tracking nicht schneller oder sogar schlechter in der Leistung sind.
Aufgrund dieser Komplikationen bei der Verwendung von Änderungsverfolgungs-Proxys besteht die bevorzugte Methode darin, standardmäßig die auf Snapshots basierende Änderungsverfolgung zu verwenden und Proxys (nach einigen Tests) nur in Situationen sorgfältig zu verwenden, in denen eine hohe Leistung erforderlich ist und sich als schneller als auf Snapshots basierende erweist Änderungsverfolgung.