Как мне скопировать объект с помощью NHibernate
Я использую Nhibernate (я полный noob), и я хочу иметь возможность скопировать объект, загруженный из базы данных, и сохранить его с новым Id... Кто-нибудь сталкивался с такой ситуацией? Любая помощь будет принята с благодарностью.
2 ответа
Мне нужно сделать именно это для очень сложного набора объектов, и я нашел следующее:
NHibernate не совсем поддерживает это.
Если вы попытаетесь просто заменить идентификатор объекта, который вы получили из сеанса, вы получите ошибку Nhibernate: идентификатор экземпляра объекта был изменен с <9ae3868d-17bf-4314-ba0c-4eb3b44b1a2e> на <2b2b67c6-a421-48c4-836c-4c27f6481718>
Если сеанс больше не знает об объектах, которые он получил, то есть, если вы удалили их перед сохранением и сбросом, то теперь будет работать только изменение идентификаторов. Таким образом, вы можете написать код так:
public void CloneStudent(Guid studentId)
{
// Get existing student
Student student = _session.Get<Student>(studentId);
// Copy by reference
Student newStudent = student;
// Reset Id to do quick and dirty clone
newStudent.Id = Guid.NewGuid();
newStudent.Sticker = "D";
// Must evict existing object or Nhibernate will throw object modified error
_session.Evict(student);
// Save new object
_session.Save(newStudent);
_session.Flush();
}
Проблема заключается в том, что если ваш объектный граф имеет какую-либо глубину, вы должны быть уверены, что удалили весь набор, и тогда вам могут понадобиться оригиналы в сеансе, но вам придется их снова извлекать. Это логистическая головная боль, и в результате получается код с очень смутными и запутанными намерениями.
Я не рекомендую.
Чаще всего делается сериализация в двоичный поток и преобразование этого потока в новый набор объектов. Хорошо, но работает, только если все ваши объекты сериализуемы.
Для меня это не так. Я пишу ручной код для создания глубоких копий графа объектов с использованием конструкторов копирования. Это сложно и также может привести к проблемам обслуживания, но если объекты не могут быть сериализованы, есть несколько лучших альтернатив.
Извините, глубокое копирование объектов остается сложной задачей, если сериализация не возможна.
Просто делать new MyClass()
и скопировать все, кроме Id. Вы можете использовать отражение для этого.