Реализовать копию объекта при обновлении NHibernate - PullRequest
0 голосов
/ 26 августа 2009

Как я могу сделать такое поведение в NHibernate:

В моем домене есть объект с именем User

// I ommit mapping attributes
public class User
{
  int Id {get; set;}
  int pId {get; set;}
  //....other props, such as Login, Name, email...
}

Мне нужно сделать полную копию при обновлении. pId должен быть установлен на оригинальный Id. Старая сущность должна быть нетронутой.

Так что это должно быть похоже на какую-то систему управления версиями, где pId - это неизменяемый идентификатор, а Id - как версия. Я пытался использовать атрибут сопоставления версий, но он просто обновляет поле версии, без воссоздания полной сущности. Какой подход будет лучше?

Ответы [ 2 ]

1 голос
/ 26 августа 2009

Я написал систему управления версиями для нашего приложения. Я разделил версионный объект на два класса: один представляет весь объект, а второй - его версии.

В нашем программном обеспечении управление версиями является частью бизнес-логики. Приложение предоставляет доступ к истории, и пользователь имеет некоторый контроль над версиями.

Поэтому в памяти создается новая версия. Вам нужно выполнить глубокую копию. Вы можете реализовать это, внедрив интерфейс в корневую сущность и все ее дочерние элементы. Этот интерфейс предоставляет метод DeepCopy, который рекурсивно вызывается через граф объектов.

Существует также защищенный метод MemberwiseCopy в object, который может быть полезен. Это не глубокая копия.

Мы не хотели, чтобы боль поддерживала код, который копирует каждое отдельное свойство. Поэтому мы используем сериализацию для копирования графа объектов в память:

public static T CopyDataContract<T>(T obj)
{
    NetDataContractSerializer serializer = new NetDataContractSerializer();
    using (MemoryStream stream = new MemoryStream())
    {
        serializer.Serialize(stream, obj);
        stream.Position = 0;
        return (T)serializer.Deserialize(stream);
    }
}

Кроме того, у нас есть методы в сущностях, которые сбрасывают идентификаторы и выполняют другую очистку. Это также делается рекурсивно через граф объектов.

Пока все работает нормально. В будущем нам, вероятно, потребуется реорганизовать его в реализацию интерфейса, что немного чище.

0 голосов
/ 26 августа 2009

В зависимости от того, является ли история НЕ частью вашей логики домена, я бы предложил использовать триггеры. Я имею в виду, что не являюсь частью доменной логики - вам не нужно показывать это пользователям, вы не делаете копии из исторической версии.

Используя триггеры, у вас есть несколько вариантов - самый простой (и подразумевающий, что вам действительно нужно сохранять историю только для нескольких таблиц) - будет иметь отдельную таблицу _history, которая является копией вашей исходной таблицы.

В целом, это действительно зависит от того, что именно вы ищете.

...