科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件用不到140行C-sharp代码开发面向对象的数据库(下篇)

用不到140行C-sharp代码开发面向对象的数据库(下篇)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在开始深入代码的细节之前,我们需要看看我们的解决方案背后的体系结构。其基本的体系结构由两个类和一个接口构成。

作者:builder.com.cn 2007年3月2日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
保存对象

在数据库被加载到XmlDBState对象之后,我们就希望将对象保存在它里面。这也可以通过XmlDBState用一个叫做“SaveObject”的方法来处理。SaveObject的代码见列表D

列表D

public static void SaveObject(IXmlDBSerializable data, bool persistData)
{
    Type type = data.GetType();
    string typeString = type.ToString();
    PropertyInfo[] properties = type.GetProperties();

    //Remove the object if it's currently in the database.
    XmlNode typeNode = RemoveCurrentObject(typeString, data);

    //Loop through each property in our object and see
    // if we need to save them in the database.
    foreach (PropertyInfo property in properties)
    {
        //Get the property's value.
        object propertyValue = property.GetValue(data, null);

        //Check to see if the property is IXmlDBSerializable,
        // and if it is save it to the database.
        if (propertyValue is IXmlDBSerializable)
            ((IXmlDBSerializable)propertyValue).Save(persistData);
        else if (propertyValue is System.Collections.ICollection)
        {
            //This property is a collection of objects.
            // We need to see if this collection contains
            // IXmlDBSerializable objects, and serialize
            // those objects if needed.
            IList propertyList = propertyValue as IList;

            //Does the collection contain IXmlDBSerializable
            // objects?
            if (propertyList != null &&
                propertyList.Count > 0 &&
                propertyList[0] is IXmlDBSerializable)
            {
                //It does contain IXmlDBSerializable objects
                // so save each of them.
                foreach (object listObject in propertyList)
                    ((IXmlDBSerializable)listObject).Save(persistData);
            }
        }
    }

    //If the type which is being saved isn't currently
    // represented in the database, create a place to
    // hold that specific type.
    if (typeNode == null)
    {
        typeNode = XmlDBState.Database.CreateElement(typeString);
        XmlDBState.MainNode.AppendChild(typeNode);
    }

    //Prepare the objects we will need for serializing
    // the object.
    XmlSerializer serializer = new XmlSerializer(type);
    StringWriter writer = new StringWriter();
    XmlDocument objectDocument = new XmlDocument();

    //Serialize the object into our StringWriter object.
    serializer.Serialize(writer, data);

    //Create an XmlDocument from our serialized object.
    objectDocument.InnerXml = writer.ToString();

    //If the serialized object had data, import it into
    // the database.
    if (objectDocument.ChildNodes.Count > 0)
    {
        //Set the object's Node property to the serialized
        // data.
        data.Node =
            XmlDBState.Database.ImportNode(objectDocument.ChildNodes[1],
                                            true);
        //Append the serialized object to the type node.
        typeNode.AppendChild(data.Node);
    }

    //If requested, persist these changes to the XML file
    // held on disk. If this is not called, the change is
    // made in memory only.
    if (persistData)
        XmlDBState.Database.Save(XmlDBState.Path);
}

这个函数毫无疑问地担当着数据库最重要的功能。下面就是这个函数从开始到结束所经历的步骤。

  • 如果对象在数据库里存在的话,它就会把这个对象删除。我们这样做的理由是,在数据库里删除序列化对象并重新保存它要比(直接)更新序列化对象容易。被调用的RemoveCurrentObject函数还会返回XmlNode,负责存留我们正在保存的对象类型。如果看一下上面的示例数据库,你会看到XmlDB.OrderXmlDB.Customer这两个节点——它们都是类型节点,一个用于保存Order对象,另一个用于保存Custom对象。
  • 在删除了当前对象之后,我们需要使用反射来检查正在被保存的对象。只有这样做我们才能够把任何子对象/集合以及主对象保存到数据库里。如果我们发现对象有必须保存的子级,那么子级就要被明确地送到IXmlDBSerializable,用来调用Save()方法。
  • 下一步,我们检查typeNode是否存,如果不存在,我们就创建一个。
  • 然后我们必须创建序列化形式的对象。使用XmlSerializer对象把对象序列化成为StringWriter对象就行了。这让我们可以通过String(字符串)访问序列化对象,然后把它导入一个临时的XmlDocument。我们把它导入XmlDocument,这样它就能够被导入到主数据库XmlDocument里了。利用主XmlDocument对象的ImportNodeAppendChild方法就能够实现这一目标。
  • 最后,如果需要的话,我们要把数据库保持到硬盘上。调用XmlDocument.Save方法并把数据库的路径作为参数传递可以达到这一目标。这会使得XmlDocument覆盖磁盘上的当前内容。把数据库写回到磁盘上的过程很缓慢,这就是为什么我们可以选择不保持数据的原因。例如,如果我们要保存10,000个对象,将这10,000保存到内存里(Save(false))然后调用XmlDBBase.Database.Save(XmlDBBase.Path)要比仅仅对10,000个对象调用Save(true)快得多。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章