使用xml文件的数据访问层

时间:2011-12-12 08:30:28

标签: c# c#-4.0 xml-serialization

我想创建一个数据访问层,支持CRUD方法,以及XML文件的底层存储 我是XML新手,我不太确定如何使用XmlDocumentXDocumentXmlSerializer等。
这是我对数据访问类的基本想法:

public class EmployeesDao
    {
        private const string FILE_NAME = "file.xml";

            //an XDocument which contains all the employees records
        private XDocument m_XDocument;
        private XmlSerializer m_XmlSerializer;


        public TestCasesDao()
        {
            //is this correct?
                    m_XDocument = XDocument.Load(@"c:\" + FILE_NAME);
            m_XmlSerializer = new XmlSerializer(typeof(EmployeeDTO));
        }

        public void Save(IEmployee employee)
        {
            var dto = new EmployeeDTO(employee);
            //TODO: serialize the DTO, add it to the XDocument, and save to file
        }

        public IEmployee GetEmployee(string name)
        {
                    //TODO: retrieve an EmployeeDTO from my XDocument
                    return employeeDto.Convert();  //return an IEmployee
        }

            //TODO: update and delete methods...
    }

有关如何填补缺失空白的任何想法?

2 个答案:

答案 0 :(得分:4)

这取决于您的需求。将XML用于DAL只对小型项目有意义,即使在这种情况下,SQLite也可能是更好的解决方案。 XML中唯一的“好处”是它是一种文本的,人类可读的格式,但从这个意义上说,它比实际的DAL技术更适合作为导出文件。任何“手工制作”单文件数据库系统的问题在于,每次进行更改时都需要保存整个文件(如果您不选择memory mapped files,根据您的需要,这可能是一种过度杀伤)。

对于每个插入或更新操作,您将需要一个阅读器和一个编写器,以便将所有记录复制到新文件。根据您的文件大小,一个选项可能是在应用程序生命周期内将记录保留在内存中,并且每隔一段时间将它们刷新到磁盘。它将是一个静态可用的列表(考虑到并发性),但只有在数据库相对较小时才有意义。

您最关心的可能是一致性和交易完整性。如果有两个进程同时使用同一XML文件,则很难同步访问。此外,应用程序崩溃或电源故障可能会使您的数据损坏,这意味着您还应该考虑某种日记系统。例如,SQLite就像第一眼看上去一样简单,是ACID,并且付出了很多努力来实现这个目标(如果你有时间,请检查this lengthy article以获得一个想法)。从头开始实施这是一个真正的过度杀伤。

总而言之,您的选择是:

  1. 您只有一个进程使用单个文件。

    一个。数据库很小:将其保存在内存中,锁定所有操作,并定期刷新。相对简单。

    湾数据库很大:

    • 使用读写器组合在每个操作上复制整个文件。很简单,但速度较慢。

    • 保留命令队列并批量清除它们。更快,增加了一些交易支持,但很复杂。

  2. 另一个进程可以访问该文件。

    一个。实施日记机制以防止同时访问。

    湾创建一个单独的服务,它将自己处理所有交易。

  3. 在任何情况下,您可能需要保留事务日志文件并使用它来确保访问之间的数据一致。您的应用应该能够自己从故障中恢复。我的观点是,SQLite可能是要走的路:结合像NHibernate这样的ORM解决方案,它使用起来非常简单和安全。

答案 1 :(得分:0)

对于序列化,您可以使用通用方法

public static class GenericSerializer
{
    public static string Serialize<T>(ICollection<T> listToSerialize)
    {
        MemoryStream stream = new MemoryStream();
        XmlSerializer xmlSerializer;
        try
        {
            xmlSerializer = new XmlSerializer(typeof(List<T>));
            xmlSerializer.Serialize(stream, listToSerialize);

            return Encoding.UTF8.GetString(stream.ToArray());
        }
        finally
        {
            stream.Close();
        }
    }

    public static string Serialize<T>(T objectToSerialize)
    {
        MemoryStream stream = new MemoryStream();
        XmlSerializer xmlSerializer;
        try
        {
            xmlSerializer = new XmlSerializer(typeof(T));
            xmlSerializer.Serialize(stream, objectToSerialize);
            return Encoding.UTF8.GetString(stream.ToArray());
        }
        finally
        {
            stream.Close();
        }
    }

  public static T Deserialize<T>(string xmlDataToeSerialize)
    {
        XmlSerializer xmlDeSerializer = new XmlSerializer(typeof(T));
        StringReader stringReader = new StringReader(xmlDataToeSerialize);
        return (T)xmlDeSerializer.Deserialize(stringReader);            
    }
}

对于更新和删除您可以从文件中检索集合或对象并编辑和覆盖现有集合或对象,也可以使用XPath表达式直接编辑XML

XML / 0340_XPath.htm“&GT; HTTP://www.java2s.com/Tutorial/CSharp/0540_ XML / 0340 _XPath.htm