EF4 POCO WCF Serialisierungsprobleme (kein Lazy Loading, Proxy / kein Proxy, Zirkelverweise usw.)

8

OK, ich möchte sicherstellen, dass ich meine Situation und alles, was ich gründlich ausprobiert habe, abdecken kann. Ich bin mir ziemlich sicher, was ich tun kann / will, aber ich habe nicht die perfekte Kombination für den Erfolg gefunden.

Ich verwende Entity Framework 4 RTM und seine POCO Unterstützung. Ich suche nach einer Entität (Config), die eine Viele-zu-viele-Beziehung mit einer anderen Entität (App) enthält. Ich deaktiviere aus dem lazy loading und deaktiviere die Proxy-Erstellung für den Kontext und lade explizit die Navigationseigenschaft (entweder durch .Include () oder .LoadProperty ()). Wenn jedoch die Navigationseigenschaft geladen ist (dh Apps werden für eine bestimmte Konfiguration geladen), enthalten die geladenen App-Objekte bereits Verweise auf die Configs, die in den Speicher geladen wurden. Dies erstellt einen Zirkelverweis .

Jetzt weiß ich, dass der von WCF verwendete DataContractSerializer zirkuläre Referenzen verarbeiten kann, indem er den preserveObjectReferences -Parameter auf true setzt. Ich habe das mit ein paar verschiedenen Attribution-Implementierungen versucht, die ich online gefunden habe. Es ist erforderlich, um zu verhindern, dass der Fehler "das Objektdiagramm enthält Zirkelbezüge und kann nicht serialisiert werden". Es verhindert jedoch nicht die Serialisierung des gesamten Graphen zwischen Config und App.

Wenn ich es über WcfTestClient.exe aufruft, bekomme ich eine stackoverflow (ha!) Ausnahme vom Client und ich werde abgespritzt. Ich erhalte unterschiedliche Ergebnisse aus verschiedenen Aufrufumgebungen (C # Unit Test mit einem lokalen Verweis auf den Webdienst scheint in Ordnung zu sein, obwohl ich immer noch endlos zwischen Configs und Apps hin- und herbohren kann, aber den Aufruf aus einer Coldfusion-Umgebung gibt nur die erste Config zurück in der Liste und Fehler aus den anderen.) Mein Hauptziel ist eine serialisierte Darstellung des Graphen, die ich explizit von EF laden (dh: Liste der Configs, jeweils mit ihren Apps, aber keine App zurück zu Config Navigation.)

HINWEIS: Ich habe auch versucht, die ProxyDataContractResolver-Technik zu verwenden und die Proxy-Erstellung in meinem Kontext aktiviert zu lassen. Dies führt dazu, dass man sich über unbekannte Arten beklagen muss. Ich habe gelesen, dass der ProxyDataContractResolver in Beta2 nicht vollständig funktioniert hat, aber in RTM funktionieren sollte.

Für eine Referenz, hier ist ungefähr, wie ich die Daten im Service abfrage:

%Vor%

Ich glaube, der Kern meines Problems ist, dass beim Laden von Navigationseigenschaften für POCO-Objekte aus Entity Framework 4 die Navigationseigenschaften für Objekte, die sich bereits im Speicher befinden, vorab ausgefüllt werden. Dies wiederum verschlingt die WCF-Serialisierung, trotz aller Bemühungen, um zirkuläre Referenzen richtig zu handhaben.

Ich weiß, dass es eine Menge Informationen gibt, aber es steht mir wirklich im Weg, mit EF4 / POCO in unserem System fortzufahren. Ich habe mehrere Artikel und Blogs gefunden, die diese Themen betreffen, aber für mein Leben kann ich dieses Problem nicht lösen. Fühlen Sie sich frei, um einfach Fragen zu stellen und mir helfen, diese Situation Brainstorming.

PS: Um die Sache gründlich zu machen, injiziere ich die WCF-Services mithilfe des HEAD-Builds von Spring.NET für die Fehlerbehebung bei Spring.ServiceModel.Activation.ServiceHostFactory. Ich glaube jedoch nicht, dass dies die Ursache des Problems ist.

BEARBEITEN: Die Klasse "ProxyDataContractResolver" funktioniert ordnungsgemäß, wenn ich keine Zirkelverweise habe. (zB: Ich setze den Setzer von App.Configs als privat, was die Serialisierung der Eigenschaft verhindert.) Es explodiert, wie es scheint, wenn es Configs über das App-Objekt anstößt - sie scheinen nicht als das erkannt zu werden gleicher Typ wie die Konfiguration der obersten Ebene.

EDIT2: Es scheint, dass entweder EF oder WCF nicht erkennt, dass die Entitäten tatsächlich gleich sind. Beispiel: 'Config' ist identisch mit einem bestimmten 'Config.Apps [x] .Configs [y]'. Die Entitätsschlüssel sind in der CSDL für jedes Modell ordnungsgemäß festgelegt, und ich habe die Funktion Equals () überschrieben, um Entitäten basierend auf ihrer Id-Eigenschaft zu vergleichen. Dies paßt zu den Symptomen, da kein zirkulärer Referenzfehler geworfen wird, obwohl es tatsächlich eine zirkuläre Referenz ist (und WcfTestClient.exe explodiert) UND der ProxyDataContractResolver explodiert, wenn er die 'Config.Apps [x] .Configs [y]' Ebene erreicht von Konfigurationen (Es ist nicht in der Lage, einen Config-Proxy zuzuordnen. Der ProxyDataContractResolver funktioniert anders. Es ist als ob er weiß, wie er mit der ersten Runde von Entitäten umgehen soll, aber die zweite Ebene, die er als unterschiedliche Entitäten betrachtet.)

Wow, ich kann wortreich sein. Entschuldigung Leute!

    
kdawg 26.05.2010, 17:07
quelle

5 Antworten

2

Vielleicht möchten Sie meinen Blogbeitrag zu diesem spezifischen Szenario besuchen - bitte mailen Sie mir, wenn dies nicht der Fall ist helfen Sie, Ihre aktuelle Lage zu reparieren! Ich habe eine Beispiellösung auch eingeschlossen.

Bitte lassen Sie mir ein Feedback zukommen, ich würde wirklich gerne von mehr Leuten zu diesem speziellen Thema hören - besonders mit den Implementierungsproblemen auf der Kundenseite.

    
RobS 13.09.2010 08:08
quelle
1

Hrmm, ich habe das Problem vielleicht nicht vollständig verstanden, aber jedes Mal, wenn ich auf zirkuläre Referenzen mit WCF stoße, lautet die Antwort, [DataContract] in den beanstandeten Klassen zu [DataContract (IsReference = true)] zu ändern.

Dies ist eine große Hilfe im Vergleich zu all den drek der Verwirrung mit den Vertragsresolver, die vor WCF 3.5 SP1 benötigt wurde.

Hoffe, das hilft.

    
tap 24.07.2010 01:18
quelle
1

Vor dem gleichen Problem heute und verwendet Value Injecter , um es zu lösen. Es ist so einfach wie:

%Vor%

Wir konnten es uns nicht leisten, ProxyCreation zu deaktivieren

    
Korayem 23.01.2012 15:18
quelle
0

Versuchen Sie, myContext.ContextOptions.ProxyCreationEnabled = false;

zu setzen

Wenn das Problem gelöst ist (wie bei mir), dann haben Sie die folgenden Schritte nicht befolgt: Ссылка

Das hat das Problem für mich gelöst.

    
Alireza Haghshenas 27.06.2010 08:23
quelle
0

Sie können ApplyDataContractResolverAttribute und a ProxyDataContractResolver zusammen mit CyclicReferencesAwareAttribute verwenden. Dies erzeugt zunächst einen Fehler wie diesen - als ob überhaupt kein DataContractResolver angegeben wäre:

  

Geben Sie 'System.Data.Entity.DynamicProxies.Whatever_E6 ...... A9' mit dem Datenvertragsnamen 'Whatever_E6 ...... A9: http: //schemas.datacontract.org/2004/07/ System.Data.Entity.DynamicProxies 'wird nicht erwartet. Ziehen Sie die Verwendung eines DataContractResolvers in Betracht oder fügen Sie statisch bekannte Typen zur Liste bekannter Typen hinzu, z. B. indem Sie das KnownTypeAttribute-Attribut verwenden oder diese zur Liste bekannter Typen hinzufügen, die an DataContractSerializer übergeben werden.

Es wird mit einer einfachen Änderung funktionieren.

Im ApplyCyclicDataContractSerializerOperationBehavior müssen die Konstruktoren für den DataContractSerializer auch den DataContractResolver übergeben. Dies wird von allen Versionen, die ich online gesehen habe, weggelassen.

Beispiel:

%Vor%     
James 12.12.2012 19:17
quelle