Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将序列化对象迁移到新版本_C#_Remoting - Fatal编程技术网

C# 将序列化对象迁移到新版本

C# 将序列化对象迁移到新版本,c#,remoting,C#,Remoting,我想将数据库中以前序列化的对象迁移到新模式 我以前的目标 Public interface MyReport { string Id { get; set;} string Name { get; set;} Dictionary<string, string> PropColl { get; set;} } 公共接口MyReport { 字符串Id{get;set;} 字符串名称{get;set;} 字典PropColl{get;set;} } 但

我想将数据库中以前序列化的对象迁移到新模式

我以前的目标

Public interface MyReport
{

    string Id { get; set;}

    string Name { get; set;}

    Dictionary<string, string> PropColl { get; set;}
}
公共接口MyReport
{
字符串Id{get;set;}
字符串名称{get;set;}
字典PropColl{get;set;}
}
但由于某些原因,我们不得不对接口进行更改

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 
}
公共接口IMarkme
{
}
公共接口MyReport,其中T:Imarkme
{
字符串Id{get;set;}
字符串名称{get;set;}
T ExtendedProp{get;set;}
}
公共NewProp:Imarkme
{
///这里有一些代码
}
如您所见,我的接口已被修改,我希望将基于MyReport序列化的序列化对象迁移到MyReport 有人能给我提供一些输入吗?我应该编写什么样的实用程序来帮助我实现将序列化对象迁移到新的修改接口版本

谢谢,
AG

我最近实际上做了类似的事情,我创建了一个简单的控制台应用程序,能够将一些序列化对象从一个版本转换到另一个版本。我只是简单地使用DLL和反射的两个版本来读取和写入不同属性的值。也许你会发现这对你的灵感很有帮助;)

1) 编写一个实用程序,读取旧对象定义中的序列化对象

2) 该实用程序以非序列化的方式将对象写入数据库(即,每个字段中都有一段数据,等等)

不要养成序列化对象的习惯,不要将对象存储在持久性存储中的某个地方,以便以后检索。序列化不是为此而构建的

在过去,您遇到了C程序员的问题:他们会在内存中创建一个结构,然后将该结构保存到文件中。然后结构的成员会改变,他们会想知道如何读回它,因为数据的编码不同

随后出现了数据库格式、INI文件等,专门用于满足这一需求,因此以一种格式保存数据,然后能够无误地读取数据

所以不要重复过去的错误。创建序列化是为了促进短期二进制存储和通过TCP/IP传输对象的能力


最坏的情况是,将数据存储为XML,而不是序列化的二进制流。另外,据我所知,微软并不能保证从一个.NET版本的序列化数据可以从另一个版本读取。尽可能将数据转换为清晰的格式。

谢谢Thomas,但我考虑的是Urrogateserialization,是的,这是一个开始。如果我能得到更多的想法和代码示例,以及如何解决这个问题,我将不胜感激。你愿意分享吗?
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;
    }