C #, проблема смешивания сериализации Xml с Nhibernate - PullRequest
2 голосов
/ 22 августа 2010

Я работаю над программой, которая использует Nhibernate для сохранения объектов и сериализацию Xml для импорта и экспорта данных. Я не могу использовать те же свойства для коллекций, что, например, Nhibernate требует, чтобы они были Ilists, потому что у него есть собственная реализация этого интерфейса, и я не могу сериализировать интерфейсы. Но так как мне нужно синхронизировать оба свойства, я подумал, что могу использовать два разных свойства для одного и того же поля. Свойства будут соответствовать тому, что мне нужно для каждого фреймворка, и они обновят поле соответствующим образом.

Итак, у меня есть следующее поле:

private IList<Modulo> modulos;

И следующие свойства:

 [XmlIgnore]
        public virtual IList<Modulo> Modulos
        {
            get { return modulos; }
            set { modulos = value; }
        }

        [XmlArray]
        [XmlArrayItem(typeof(Modulo))]
        public virtual ArrayList XmlModulos
        {
            get
            {
                if (modulos == null) return new ArrayList();
                var aux = new ArrayList();
                foreach (Modulo m in modulos)
                    aux.Add(m);
                return aux;
            }
            set
            {
                modulos = new List<Modulo>();
                foreach (object o in value)
                    modulos.Add((Modulo)o);
            }

        }

Первый работает отлично, вполне стандартно, но у меня есть проблемы со вторым. Get работает отлично, так как у меня нет проблем с сериализацией объектов (это означает, что он правильно берет информацию из поля). Но когда мне нужно десериализовать, он не получает всю информацию. Отладчик сообщает, что после десериализации поле не обновляется (ноль), а свойство пусто (счет = 0).

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

Есть идеи, как я могу изменить свою собственность, чтобы она делала то, что я хочу? Любая помощь будет оценена.

1 Ответ

1 голос
/ 11 марта 2011

Короткий ответ: вы не можете.

Обычно вы создаете DTO (объект передачи данных) отдельно от ваших объектов NHibernate. Например:

    public class PersonDto
    {
      [XmlAttribute(AttributeName = "person-id")]
      public int Id { get; set; }

      [XmlAttribute(AttributeName = "person-name")]
      public string Name{ get; set; }
    }

На ваш объект DTO вы помещаете только те свойства, которые вы намерены сериализовать. Затем вы создаете DTO из своей доменной модели, когда вам нужно ее сериализовать.

Существует отличная небольшая библиотека с именем automapper, которая делает отображение ваших доменных объектов на довольно простой. Смотри: http://automapper.codeplex.com/

Вот пример класса person, который поддерживает сопоставление с указанным DTO.

public class Person
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }

    static Person()
    {
        Mapper.CreateMap<PersonDto, Person>();
        Mapper.CreateMap<Person, PersonDto>();
    }

    public Person(PersonDto dto)
    {
        Mapper.Map<PersonDto, Person>(dto, this);
    }

    public PersonDto ToPersonDto()
    {
        var dto = new PersonDto();
        Mapper.Map<Person, PersonDto>(this, dto);
        return dto;
    }
}
...