2009-08-11 5 views
9

Ich habe Daten, die unter Verwendung von binärer Serialisierung für die folgende Klasse gespeichert wurde:Wie deserialize ich alte Daten für einen Typ, der geändert wurde?

[Serializable] 
public abstract class BaseBusinessObject 
{ 
    private NameValueCollection _fieldErrors = new NameValueCollection(); 

    protected virtual NameValueCollection FieldErrors 
    { 
     get { return _fieldErrors; } 
     set { _fieldErrors = value; } 
    } 

    ... 
} 

Irgendwann wurde die Klasse dazu geändert:

[Serializable] 
public abstract class BaseBusinessObject 
{ 
    private Dictionary<string, string> _fieldErrors = new Dictionary<string, string>(); 

    protected virtual Dictionary<string, string> FieldErrors 
    { 
     get { return _fieldErrors; } 
     set { _fieldErrors = value; } 
    } 

    ... 
} 

Diese Probleme verursachen Deserialisieren alte Daten.

Mein erster Gedanke war, ISerializable zu implementieren, aber diese Klasse hat zahlreiche Eigenschaften sowie Hunderte von erbenden Klassen, für die ich dies auch implementieren müsste.

Ich möchte entweder die alten Daten ändern, um während der Deserialisierung mit der aktuellen Struktur übereinzustimmen, oder die alten Daten sauber aktualisieren.

Antwort

4

Fügen Sie die neue _ fieldErrors unter einem anderen Namen, sagen _fieldErrors2, und machen Sie [Optional]. Implementieren Sie dann eine [OnDeserialized]-Methode, die die Daten von _fieldErrors zu _fieldErrors2 (falls vorhanden) kopiert und _fieldErrors löscht.

+0

Dies bot die realistischste Herangehensweise für meine Bedürfnisse, aber ich ging eine andere Route hinunter. – ramnik

3

Wenn die Daten nur intern verwendet werden, wäre mein erster Gedanke, einen einfachen Wegwerfcode zu schreiben, um Ihre Binärdaten mit der alten "NameValueCollection" zu deserialisieren, sie einem Dictionary zuzuordnen und erneut zu serialisieren. Auch wenn es einige Tage dauert, alle Daten zu verarbeiten, lohnt es sich nicht, einen Patch für den neuen Code zu implementieren, um die alten Daten zu unterstützen.

Auch wenn es nicht nur intern verwendet wird, scheint ein Importeur der einfachste Weg zu sein.

2

Zu OlivierDs guten Rat hinzufügen, würde ich vorschlagen, dass Sie beide Klassen definieren, aber zuerst versuchen, als die aktuelle Version zu deserialisieren. Deklarieren Sie es in Ihrem catch-Block als Legacy-Version, aktualisieren Sie es dann auf die aktuelle und speichern Sie es zurück. Wenn keine Instanzen der älteren Version vorhanden sind, können Sie den Code entfernen.

0

Nach ein paar Optionen zu untersuchen, habe ich die folgenden Schlussfolgerungen:

Idealerweise würde ich in der Lage sein, den Wert aus den ursprünglichen NameValueCollection zuzugreifen und sie manuell zu Dictionary<string, string> konvertieren. Der einzige Weg dies zu tun wäre die Implementierung von ISerializable, aber dies stellte zwei Hauptprobleme dar: Übereinstimmung mit der Benennung der Altdaten und die Einbeziehung der Serialisierungslogik für alle erbenden Klassen (von denen es Hunderte gibt).

Effektiv, das brachte mich in eine Bindung. Glücklicherweise konnte ich feststellen, dass dieses Feld wirklich nur als Zusammenfassung von Formularüberprüfungsfehlern verwendet wird und von vornherein nicht serialisiert werden sollte. Daher habe ich es von der Serialisierung ausgeschlossen.

Verwandte Themen