我正在使用Nhibernate(我是一个完整的菜鸟),我希望能够做的是复制从数据库加载的实体并用新的ID保存...有没有人遇到这种情况?任何帮助将非常感激。
答案 0 :(得分:9)
只需执行new MyClass()
并复制除Id之外的所有内容。你可以使用反射。
答案 1 :(得分:5)
我需要为一组非常复杂的对象做到这一点,到目前为止我发现的是:
NHibernate并不完全支持这一点。
如果您尝试简单地替换从会话中获得的对象的Id,您将收到Nhibernate错误:实例的标识符已从< 9ae3868d-17bf-4314-ba0c-4eb3b44b1a2e>中更改。至< 2b2b67c6-a421-48c4-836c-4c27f6481718>
如果会话不再知道它检索到的对象,即如果在保存和刷新之前将其逐出,则只需更改ID即可。所以你可以写这样的代码:
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();
}
问题在于,如果您的对象图有任何深度,您必须确保逐出整个集,然后您可能需要会话中的原件仍然需要再次检索它们。这是一个后勤问题,并且会产生非常模糊和错综复杂的代码。
我不推荐。
更常见的是序列化为二进制流并将此流重构为一组新对象。很好,但只有在您的对象都可序列化时才有效。
对我来说情况并非如此,我正在做的是编写手动代码,使用复制构造函数制作对象图的深层副本。这很复杂,也可能导致维护问题,但如果对象无法序列化,那么几乎没有更好的选择。
抱歉,如果不能选择序列化,深度复制对象仍然是一项复杂的任务。