слой доступа к данным с использованием XML-файлов - PullRequest
3 голосов
/ 12 декабря 2011

Я хочу создать слой доступа к данным, поддерживающий методы CRUD, с базовым хранилищем файлов XML.
Я новичок в XML и не совсем уверен, как работать с XmlDocument, XDocument, XmlSerializer и т.д ..
Вот моя основная идея для класса доступа к данным:

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 ]

4 голосов
/ 12 декабря 2011

Это действительно зависит от ваших потребностей. Использование XML для DAL имеет смысл только для небольшого проекта, и даже в этом случае SQLite может быть лучшим решением. Единственное «преимущество» в XML заключается в том, что он представляет собой текстовый формат, удобочитаемый для человека, но в этом смысле он лучше служит экспортным файлом, чем действительной технологией DAL. Проблема с любой «сделанной вручную» единой файловой системой БД заключается в том, что вам нужно сохранять весь файл каждый раз, когда вы вносите изменения (если вы не выберете отображенных в память файлов , что может быть излишним в зависимости от ваших потребностей).

Для каждой операции вставки или обновления вам понадобятся программа чтения и записи, чтобы скопировать все записи в новый файл. В зависимости от размера файла, один из вариантов может заключаться в том, чтобы хранить записи в памяти в течение срока службы приложения и время от времени сбрасывать их на диск. Это был бы статически доступный список (с учетом параллелизма), но он имеет смысл только в том случае, если база данных относительно мала.

Ваша самая большая проблема может быть последовательность и целостность транзакций. Если у вас два процесса, использующих один и тот же XML-файл одновременно, синхронизировать доступ будет сложно. Кроме того, сбой приложения или сбой питания могут привести к повреждению данных, а это значит, что вам следует подумать о какой-то системе журналирования. Например, SQLite, на первый взгляд простой, выглядит как ACID и прилагает немало усилий для достижения этой цели (если у вас есть время, проверьте эту длинную статью чтобы получить представление). Реализация этого с нуля - это настоящее излишество.

Итак, подведем итог, ваши варианты:

  1. У вас есть только один процесс, использующий один файл.

    а. База данных небольшая: храните ее в памяти, блокируйте все операции и регулярно очищайте. Относительно просто.

    б. База данных большая:

    • использовать комбинацию чтения / записи для копирования всего файла в каждой операции. Очень просто, но медленнее.

    • хранить очереди команд и сбрасывать их партиями. Быстрее, добавляет некоторую поддержку транзакций, но сложно.

  2. Другой процесс может получить доступ к файлу.

    а. реализовать механизм ведения журнала для предотвращения одновременного доступа.

    б. создайте отдельный сервис, который будет обрабатывать все транзакции сам.

В любом случае вам может потребоваться сохранить файл журнала транзакций и использовать его для обеспечения согласованности данных между обращениями. Ваше приложение должно быть в состоянии самостоятельно восстанавливаться после сбоев. Мое мнение таково, что SQLite - это, вероятно, правильный путь: в сочетании с решением ORM, таким как NHibernate, он действительно прост и безопасен в использовании.

0 голосов
/ 12 декабря 2011

Для сериализации вы можете использовать общие методы

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 "> http://www.java2s.com/Tutorial/CSharp/0540_XML/0340_XPath.htm

...