Мне нужно сделать именно это для очень сложного набора объектов, и до сих пор я нашел:
NHibernate не совсем поддерживает это.
Если вы попытаетесь просто заменить Id объекта, который вы получили от сеанса, вы получите ошибку 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();
}
Проблема в том, что если ваш объектный граф имеет какую-либо глубину, вы должны быть уверены, что удалили весь набор, а затем вам могут понадобиться оригиналы в сеансе, но вам придется их снова извлекать. Это логистическая головная боль, и в результате получается код с очень смутными и запутанными намерениями.
Я не рекомендую.
Чаще всего делается сериализация в двоичный поток и преобразование этого потока в новый набор объектов. Хорошо, но работает, только если все ваши объекты сериализуемы.
Это не так для меня, я пишу ручной код для создания глубоких копий графа объектов с использованием конструкторов копирования. Это сложно и также может привести к проблемам обслуживания, но если объекты не могут быть сериализованы, есть несколько лучших альтернатив.
Извините, глубокое копирование объектов остается сложной задачей, если сериализация невозможна.