2009-08-11 8 views
9

devo dati che sono stati memorizzati utilizzando la serializzazione binaria per la seguente classe:Come deserializzare i vecchi dati per un tipo che è cambiato?

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

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

    ... 
} 

Ad un certo punto, la classe è stato cambiato a questo:

[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; } 
    } 

    ... 
} 

questo sta causando problemi di deserializzazione vecchi dati.

Il mio primo pensiero è stato quello di implementare ISerializable, ma questa classe ha numerose proprietà e centinaia di classi ereditarie che avrei dovuto implementare anche per questo.

Vorrei cambiare i vecchi dati per adattarli alla struttura corrente durante la deserializzazione o avere un modo pulito per aggiornare i vecchi dati.

risposta

4

Aggiungere il nuovo _ fieldErrors con un altro nome, ad esempio _fieldErrors2 e trasformarlo in [Optional]. Quindi implementare un metodo [OnDeserialized] che copia i dati da _fieldErrors a _fieldErrors2 (se presente) e deseleziona _fieldErrors.

+0

Questo ha fornito l'approccio più realistico per le mie esigenze, ma ho finito per percorrere una strada diversa. – ramnik

3

Se i dati vengono utilizzati solo internamente, il mio primo pensiero sarebbe quello di scrivere un semplice codice throw-away per deserializzare i dati binari usando il vecchio "NameValueCollection", mapparlo a un dizionario e ricor- gerizzarlo di nuovo. Anche se ci vorranno alcuni giorni per elaborare tutti i dati, non sembra che valga la pena implementare una patch sul nuovo codice per supportare i vecchi dati.

Anche se non solo viene utilizzato internamente, un importatore sembra la soluzione più semplice.

2

In aggiunta al buon consiglio di OlivierD, suggerirei di definire entrambe le classi ma inizialmente provare a deserializzare come versione corrente. Nel blocco catch, deserializzare come versione legacy, quindi aggiornarlo a quello corrente e salvarlo nuovamente. Se non esistono istanze della versione legacy, è possibile rimuovere il codice.

0

Dopo aver esaminato alcune opzioni, ho fatto le seguenti conclusioni:

Idealmente mi sarebbe in grado di accedere al valore dall'originale NameValueCollection e manualmente convertirlo in Dictionary<string, string>. L'unico modo per farlo sarebbe quello di implementare ISerializable, ma questo ha posto due problemi principali: la corrispondenza fino alla denominazione dei dati legacy e l'inclusione della logica di serializzazione per tutte le classi ereditarie (di cui ce ne sono centinaia).

In effetti, questo mi ha messo in un vicolo cieco. Fortunatamente, sono stato in grado di determinare che questo campo viene realmente utilizzato solo come un riepilogo degli errori di convalida del modulo e non deve essere serializzato in primo luogo, pertanto l'ho escluso dalla serializzazione.

Problemi correlati