Könnte jemand Ratschläge geben oder auf Blogs / Artikel hinweisen, die bei dieser Entscheidung helfen könnten? Die Proxies scheinen mir sehr fremd zu sein und ich zögere, sie zu verwenden. Ich mag die Möglichkeit, Lazy Loading mithilfe virtueller Eigenschaften in meinem Modell zu steuern, aber das sind so ziemlich alle Vorteile, die ich sehen kann. Meine Anwendung ist eine einfache MVC-Webanwendung, und ich muss keine Hooks in den Kontext einbinden, wenn die Entitäten einen geänderten Status haben.
Wie auch immer, hier ist meine sehr begrenzte Liste von Vor- und Nachteilen. Lassen Sie mich wissen, ob ich mit irgendetwas davon nicht auf der Basis bin.
Vorteile
- Bei "Speichern" oder "Aktualisieren" wird "Apply'Changes" nahtlos.
- Lazy-Loading-Konfiguration ist sehr einfach.
Nachteile
- Ich habe noch nie zuvor Proxies für meine Entitäten verwendet. Dies ist eine Änderung des Ansatzes, die für mich und andere Teammitglieder nur unangenehm erscheint.
- Umständlich zu debuggen.
- Benötigt zusätzlichen Code, wenn ich serialisieren / de-serialisieren möchte
- Bei 'Speichern' oder 'Aktualisieren' muss der Proxy dasselbe Objekt sein, das aus dem Kontext abgerufen wurde.
Antworten:
Wenn Sie über dynamische Proxys in EF sprechen, müssen zwei verschiedene Typen unterschieden werden:
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 ausvirtual
.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 istDbContext
) 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.
quelle
if (DisableProxy) { context.Configuration.ProxyCreationEnabled = false; context.Configuration.LazyLoadingEnabled = false; }
I konnte ich zulassen, dass diese dynamischen Proxys serialisiert werden können, ohne dass Zirkelverweisfehler auftreten. Vielen Dank! +1Lesen Sie für alle Benutzer von Entity Framework 5 unbedingt den Artikel zu Leistungsüberlegungen.
Sections 5 NoTracking Queries
und8 Loading Related Entities
bietet die Informationen, die Sie benötigen, um eine fundierte Entscheidung zu treffen. Prost.quelle
Ich würde vorschlagen, KEINE Proxys zu verwenden. Die dynamische Proxy-Erstellung unterbricht oder verursacht Komplikationen für Komponenten, die von der Überprüfung des Laufzeit-Typs abhängig sind.
Automapper löst beispielsweise zur Laufzeit einen Typkonflikt / unerwarteten Typfehler aus, da Ihre Entitäten zur Laufzeit dynamisch Proxy-Typen generiert haben und nicht die Typen, die Sie bei der Konfiguration der automatischen Zuordnung übergeben haben.
quelle
Obwohl dynamische Proxys einige nette Funktionen haben, können sie in Wirklichkeit viele seltsame und undurchsichtige Fehler verursachen.
Zum Beispiel hat eine private Variable einer Entität in einer meiner Klassen beibehalten (es wurde ein Stapelprozess implementiert) und ich habe einige Millionen Datensätze durchlaufen, sie verarbeitet und in Stapel eingefügt und den Datenkontext für alle n Datensätze neu erstellt Reinigen Sie den Speicher. Obwohl ich die private Variable NIE verwendet habe, hat EF sie mit meinen neuen Objekten verknüpft (es gab eine Referenz über eine Navigationseigenschaft), obwohl ich nur die Referenz-ID festgelegt habe.
Dies führte dazu, dass alle Objekte während der gesamten Laufzeit des Prozesses im Speicher blieben. Ich musste AsNoTracking verwenden und Proxys deaktivieren, damit der Prozess wie erwartet funktioniert und Speicher und Leistung wieder auf das normale Niveau zurückkehren. Beachten Sie, dass Proxys auch auf den Kontext verweisen, in dem sie erstellt wurden, und dass dadurch riesige Diagramme von Entitäten gespeichert werden können. Es ist fast unmöglich, sie zu debuggen
Ich bin daher der Meinung, dass Sie die Proxys global deaktivieren und in kleinen und enthaltenen Codeteilen aktivieren sollten. Es ist sehr gefährlich und unmöglich, solche Probleme zu debuggen, insbesondere wenn große Teams codieren.
Die Änderungsverfolgung ist nett, sie könnte die Verwendung an einigen Stellen rechtfertigen. Das verzögerte Laden kann ein großes Problem bei der Leistung und Serialisierung sein, es sei denn, Sie wissen, was Sie tun. Ich bevorzuge jederzeit eifriges oder explizites Laden.
quelle
Verwenden Sie Automapper 4.2.1. Neue Version hat keine DynamicMap
var parents = parentsRepo.GetAll().ToList(); Mapper.CreateMap<Parent,ParentDto>(); var parentsDto = Mapper.DynamicMap<List<ParentDto>>(parents);
quelle