现在的位置: 首页 > 综合 > 正文

对多重继承的实体类的xml序列化(数据备份)解决方案

2013年08月16日 ⁄ 综合 ⁄ 共 2186字 ⁄ 字号 评论关闭

由于最近用DB4O做一个项目,遇到了一个问题:

问题描述

DB4O对数据结构的要求非常严格 ,当实体类的数据结构变化(如增加一个属性、减少一个属性、改变继承关系),那么之前存进去的数据(即没有按照这个新的数据结构store进去的数据) 就查不出来了。可是在实际开发过程中,改变数据结构是一个较容易发生的事情。那么,怎么快速将老的数据结构下的数据进行备份和恢复呢?

对策:

使用dotnet自带的实体类向xml转化的类来转化为xml保存数据。

操作方案:

对实体类的声明前加入[Serializable],不需要保存的字段前加入 [XmlIgnore]。其他根据需要,写入特性。序列化方法:

  public virtual bool  BackupToXml(string path)
        {
            FileStream fs = null;
            try
            {
              
                if (!File.Exists(path))
                    fs = File.Create(path);
                else
                    fs = File.OpenWrite(path);

                IObjectSet allData = this.GetAll();
                XmlSerializer xsl = new XmlSerializer(this.GetType());

                foreach (object o in allData)
                {
                    xsl.Serialize(fs, o);
                }
                return true;
            }
            finally
            {
                fs.Flush();
                fs.Close();
                fs.Dispose();
               
            }
           
        }

进一步的问题

当我进行序列化的时候,有这样一种情况:P类为父类,C类为子类,而CC是C的子类,即一个2重的继承。这个时候,序列化CC的时候,会报错说 需要XmlInclude或者SoupInclude。这种情况应该是说CC类中的父类C类找不到序列化条件。

进一步的解决方案

首先,在CC类中利用特性申明[XmlInclude(typeof(C))]特性,结果问题照旧。再次尝试SoupInclude,改变格式等,依旧不行。

后来在msdn去看XmlSerializer类的帮助,结果没有这方面的资料。一度陷入困境。

最后,在网上看到一篇文章,霍然开朗。原来,XmlInclude是对的,只是不应该是写在CC的特性,而是应写在C类中,而且CC类中应该继承IComparable<T>,重写IComparable<T>.CompareTo(T)方法,这样序列化类才知道怎么判断找到哪个父类的实例。至此,问题解决。

参考资料来源:

Allen Lee's Magic - 博客园

附件:父类声明

[Serializable]
    [XmlInclude(typeof(Works))]
    [XmlInclude(typeof(LiveExperience2))]
    public class LiveExperience:BaseItem,IComparable<LiveExperience>

群里认识的朋友葡萄:

Pootow 09:33:36
关于备份和恢复,备份:只要拷贝数据库文件就可以备份了,Db4o还提供了备份的API,参见IExtObjectContainer#Backup(string path)

Pootow 09:36:17
恢复:db4o没有恢复功能。但是它提供了几种方案防止数据库文件损毁,1.IConfiguration#LockDatabaseFile(bool),如果有两个Db4o同时写入同一个数据库文件,那么数据库文件将会立刻完蛋

ootow 09:41:12
2. IConfiguration#FlushFileBuffers(bool),默认情况(False),Db4o把更改写入文件系统,但是文件系统会缓存写入,如果这时发生意外停电,宕机,数据就会丢失,如果你设置这个为True,那么Db4o会强制文件系统不做优化,每次Commit都执行写入操作,这样会造成性能下降,严重的话还会损伤硬盘(就像早期BT伤硬盘一样)。
Pootow 09:41:15
没了……
Pootow 09:41:20
就这些。。。
Pootow 09:41:46
需要顺便提醒一下的是,DB4o的数据库需要定期Defragment
Pootow 09:46:55
原因是删除的数据仍然会被保存,只是被Hide了,甚至还能用专门的函数读取删除的值!那当然一定会占用硬盘空间咯,所以Defragment会真正删除已经删除的对象,减小你的数据库文件。此外,db4o备份,最好数据库文件跟你的Assambly一起备份。

 

抱歉!评论已关闭.