2010-02-04 3 views
1

Je souhaite migrer les objets précédemment sérialisés dans la base de données vers un nouveau schéma.Migrer des objets sérialisés vers la nouvelle version

Mon objet précédent.

Public interface MyReport 
{ 

    string Id { get; set;} 

    string Name { get; set;} 

    Dictionary<string, string> PropColl { get; set;} 
} 

Mais pour certaines raisons nous avons dû faire l'interface change

Public interface IMarkme 
{ 
} 

Public interface MyReport<T> where T : Imarkme 
{ 

    string Id { get; set;} 

    string Name { get; set;} 

    T ExtendedProp { get; set;} 
} 

Public NewProp : Imarkme 
{ 
    /// some code here 
} 

Comme vous pouvez voir mon interface a été modifiée et je voudrais migrer mes objets sérialisés qui ont été sérialisé basés sur MyReport à MyReport Quelqu'un peut-il me fournir des informations sur le type d'utilitaire que je devrais écrire, ce qui peut m'aider à migrer mon objet sérialisé vers une nouvelle version d'interface modifiée.

Merci, AG

Répondre

1

j'ai effectivement fait quelque chose de similaire récemment, où j'ai créé une application simple de la console pour pouvoir transformer certains objets sérialisés d'une version à l'autre. J'ai simplement utilisé les deux versions de DLL et de réflexion pour lire et écrire les valeurs de différentes propriétés. Probablement vous il été utile comme source d'inspiration;)

static void Main(string[] args) 
    { 
     object test; 

     AppDomain.CurrentDomain.AssemblyResolve += domain_AssemblyResolve; 


     using (var con = new SqlConnection(connectionString)) 
     { 
      using (var cmd = new SqlCommand()) 
      { 
       cmd.CommandText = "select top 1 Data_Blob from dbo.Serialized"; 
       cmd.CommandType = CommandType.Text; 
       cmd.Connection = con; 

       con.Open(); 
       var blob = (byte[])cmd.ExecuteScalar(); 

       var bf = new BinaryFormatter(); 
       var stream = new MemoryStream(blob); 
       bf.AssemblyFormat = FormatterAssemblyStyle.Full; 
       test = bf.Deserialize(stream); 
      } 
     } 

     var objNewVersion = Activator.CreateInstance(Type.GetType("ObjectGraphLibrary.Test, ObjectGraphLibrary, Version=1.0.0.10, Culture=neutral, PublicKeyToken=33c7c38cf0d65826")); 


     var oldType = test.GetType(); 
     var newType = objNewVersion.GetType(); 

     var oldName = (string) oldType.GetProperty("Name").GetValue(test, null); 
     var oldAge = (int) oldType.GetProperty("Age").GetValue(test, null); 

     newType.GetProperty("Name").SetValue(objNewVersion, oldName, null); 
     newType.GetProperty("DateOfBirth").SetValue(objNewVersion, DateTime.Now.AddYears(-oldAge), null); 


     Console.Read(); 
    } 

    static Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
     var assName = new AssemblyName(args.Name); 

     var uriBuilder = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); 
     var assemblyPath = Uri.UnescapeDataString(uriBuilder.Path); 
     var codeBase = Path.GetDirectoryName(assemblyPath); 

     var assPath = Path.Combine(codeBase, string.Format("old\\{0}.{1}.{2}.{3}\\{4}.dll", assName.Version.Major, 
               assName.Version.Minor, assName.Version.Build, 
               assName.Version.Revision, assName.Name)); 

     return File.Exists(assPath) ? Assembly.LoadFile(assPath) : null; 
    } 
+0

Merci Thomas, mais je pensais à ISurrogateSerialization, mais ouais c'est un début. J'apprécierai toujours si je peux obtenir plus d'idées et d'échantillons de code comme comment je peux rencontrer ce problème. – netmatrix01

+0

Salut Netmatrix, Avez-vous trouvé une autre solution. Voulez-vous partager? – Saghar

0

1) Ecrire un utilitaire qui lit les objets sérialisés dans l'ancienne définition de l'objet.

2) L'utilitaire écrit vos objets dans la BD de manière non sérialisée (c'est-à-dire avec une donnée dans chaque champ, etc ...). Ne pas prendre l'habitude de sérialiser des objets, et stocker le quelque part dans le stockage persistant pour la récupération (beaucoup) plus tard. La sérialisation n'a pas été construite pour cela.

Vous avez déjà rencontré le problème des programmeurs en C: ils créeraient une structure en mémoire, enregistreraient cette structure dans un fichier. Alors les membres de la structure changeraient, et ils se demanderaient comment le relire, puisque les données ont été codées différemment. Ensuite, il y a eu des formats de base de données, des fichiers INI, etc., pour répondre à ce besoin, en enregistrant les données dans un format, puis en les lisant sans erreur. Par conséquent, ne répétez pas les erreurs du passé. La sérialisation a été créée pour faciliter le stockage binaire à court terme et la possibilité de transmettre, par exemple, un objet sur TCP/IP.

Au pire, stockez vos données au format XML, pas en tant que flux binaire sérialisé. En outre, il n'y a aucune garantie que MS sait que les données sérialisées d'une version de .NET pourront être lues par une autre. Convertissez vos données dans un format lisible lorsque vous le pouvez.

Questions connexes