.NET XmlSerializer und mehrere Referenzen auf das gleiche Objekt

8

Mein Repository hat List<Student> , List<Course> und List<Enrolment> , wenn eine Registrierung Enrolment.Student und Enrolment.Course enthält, die Referenzen auf einen der Studenten oder Kurse in den beiden vorherigen Listen sind.

Wenn ich XmlSerializer in meinem Repository verwende, gibt es redundante Daten aus, da es alle Eigenschaften jedes Schülers in List<Student> serialisiert, und dann wieder für jede Referenz auf dieselben Schüler in List<Enrolment> . Ich suche nach einem eleganten Weg, um das zu lösen.

Nach der Deserialisierung kann ich die Referenzen mit den ID-Werten in den doppelten Objekt-Instanzen korrigieren, die durch die Deserialisierung erzeugt wurden, aber das scheint hackisch zu sein.

Eine Methode, um die redundante Ausgabe zu beheben, besteht darin, XmlIgnore Enrolment.Student und Enrolment.Course zu erstellen und zwei weitere Eigenschaften für die Serialisierung zu erstellen - Enrolment.StudentID und Enrolment.CourseID. Während der Deserialisierung können die Referenzen für Enrolment.Student und Enrolment.Course jedoch nicht gesetzt werden (AFAIK), da die Ergebnisse der Deserialisierung von List<Student> und List<Course> nicht verfügbar sind.

Eine andere Methode, an die ich gedacht habe, ist, in meiner Objekthierarchie weiter unten zu serialisieren, indem ich jede meiner Listen einzeln mache und die Reihenfolge der Deserialisierung kontrolliere - das tue ich eher nicht.

Eine andere Methode wäre, XmlIgnore List<Enrolment> zu erstellen und eine Helper-Klasse für die Registrierungserialisierung zu erstellen, die List<Enrolment> initialisiert, nachdem die Deserialisierung abgeschlossen ist. Das scheint sehr mühsam zu sein.

Wie serialisieren / deserialisieren andere Personen mehrere Verweise auf dasselbe Objekt mit XmlSerializer?

    
Luke Rohde 08.01.2010, 08:13
quelle

4 Antworten

3

Oh die Schmerzen der Serialisierung: - & gt; ...

Es gab nie eine generische Lösung dafür. Ich denke, deshalb hat MS es aus dem Silverlight-Framework entfernt.

Ich verlasse mich nie auf irgendwelche automatischen Serialisierungsmechanismen des .net-Frameworks. Für meine eigenen Modelle und Repositories weiß ich normalerweise oder kann leicht programmatisch bestimmen, welche Eigenschaften einfache Skalare sind (Zahlen / Strings / etc) und welche Links zu anderen Objekten sind (und welche Listen von beiden sind).

Es gibt grundsätzlich zwei Szenarien:

1: Wir wollen nur die flachen Informationen von Objekten serialisieren / übertragen. In diesem Fall übertrage ich nur die entsprechenden IDs für Eigenschaften, die mit anderen Objekten verknüpft sind. Der Empfänger kann dann weitere Abfragen durchführen, um alle anderen benötigten Objekte zu erhalten.

2: Wir möchten so viele Informationen wie möglich übertragen, d. h. tiefer verschachteltes XML mit mehreren Ebenen, hauptsächlich für einige Berichtsfunktionen, die alles direkt anzeigen, indem Sie nur einige CSS auf dem XML verwenden. In diesem Fall ist es eigentlich erwünscht, dass Objekte, die identisch sind, mehrfach in die XML-Baumstruktur aufgelöst werden.

Manchmal muss ich das erste Szenario ein wenig anpassen, um zu viele nachfolgende Abfragen zu vermeiden, aber normalerweise verstehe ich mich sehr gut. I.e. Ich habe in unsere Code-Basis eingebaut, dass wir angeben können, welche zusätzlichen Objekte wir wann auflösen und / oder ob sie irgendwo konfiguriert werden sollen.

    
herzmeister 08.01.2010, 11:25
quelle
2

Es gibt keine Lösung für dieses Problem mit dem XML-Serializer. Es hat kein Identitätskonzept, mit dem es Duplikate entfernen könnte.

Das Beste, was Sie tun können, ist, den Pool von Objekten getrennt von ihren Referenzen zu serialisieren. Sie können dann Ihre Listen nach der Deserialisierung neu erstellen.

Übrigens, ist Ihnen bekannt, dass der XmlSerializer nicht für C # spezifisch ist?

    
John Saunders 08.01.2010 08:22
quelle
2

Sie können die Schnittstelle IXmlSerializable zur Registrierung implementieren und in der Methode WriteXml Studenten- und Kurs-XML generieren, die nur Schlüssel enthalten, z. B .:

%Vor%

und in der ReadXml-Methode können Sie Referenzen von diesem laden. Sie müssen außerdem das XmlIgnore-Attribut auf die Eigenschaft Student und Course setzen.

    
Jan Remunda 08.01.2010 08:32
quelle
0

Wie klingt das als Lösung:

  1. XMLIgnoriere jeden sekundären Bezug zB Enrolment.Student & amp; Einschreibung.Kurs
  2. Erstellen Sie eine Eigenschaft für jede Sekundärseite Referenz, die verwendet wird Serialisierung / Deserialisierung eines Fremdschlüssels für diese Referenz stattdessen - Präfix mit XML_FK. zB XML_FK_Student & amp; XML_FK_Course
  3. Erstellen Sie eine Methode XML_FinalizeDeserialization das ist nach Deserialisierung aufgerufen, um zu laden die Referenzen verwenden diese fremd Schlüsseleigenschaften.
Luke Rohde 08.01.2010 14:30
quelle