如何使用NHibernate复制对象

时间:2010-10-29 22:23:24

标签: c# .net nhibernate fluent-nhibernate

我正在使用Nhibernate(我是一个完整的菜鸟),我希望能够做的是复制从数据库加载的实体并用新的ID保存...有没有人遇到这种情况?任何帮助将非常感激。

2 个答案:

答案 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();


    }

问题在于,如果您的对象图有任何深度,您必须确保逐出整个集,然后您可能需要会话中的原件仍然需要再次检索它们。这是一个后勤问题,并且会产生非常模糊和错综复杂的代码。

我不推荐。

更常见的是序列化为二进制流并将此流重构为一组新对象。很好,但只有在您的对象都可序列化时才有效。

对我来说情况并非如此,我正在做的是编写手动代码,使用复制构造函数制作对象图的深层副本。这很复杂,也可能导致维护问题,但如果对象无法序列化,那么几乎没有更好的选择。

抱歉,如果不能选择序列化,深度复制对象仍然是一项复杂的任务。