如何使用 NHibernate 复制对象

发布于 2024-09-29 19:29:25 字数 91 浏览 3 评论 0原文

我正在使用 Nhibernate(我是一个十足的菜鸟),我想要做的是复制从数据库加载的实体并使用新的 Id 保存它......有人遇到过这种情况吗?任何帮助将不胜感激。

I am using Nhibernate (I am a complete noob), and what I want to be able to do is copy an entity that is loaded from the database and save it with a new Id... has anyone run into this situation? Any help would be very appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红焚 2024-10-06 19:29:25

只需执行 new MyClass() 并复制除 Id 之外的所有内容。您可以为此使用反射。

Just do new MyClass() and copy everything except the Id. You can use reflection for that.

夏の忆 2024-10-06 19:29:25

我需要对一组非常复杂的对象执行此操作,到目前为止我发现的是:

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


    }

这样做的问题是,如果你的对象图有任何深度,你必须确保驱逐整个集合,然后你可能需要会话中的原始数据,但你仍然必须再次检索它们。这是一个令人头疼的逻辑问题,并且会产生意图非常模糊且复杂的代码。

我不推荐。

更常见的做法是序列化为二进制流并将该流重新构成一组新的对象。很好,但只有当你的对象都是可序列化的时候才有效。

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

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

I need to do exactly this for a very complex set of objects and what I have found so far is:

NHibernate does not exactly support this.

If you try to simply replace the Id of an object you got from a session, you will get an Nhibernate error: identifier of an instance of was altered from <9ae3868d-17bf-4314-ba0c-4eb3b44b1a2e> to <2b2b67c6-a421-48c4-836c-4c27f6481718>

If the session no longer knows about the objects it retrieved, i.e if you evict them before saving and flushing, just changing the ids will now work. So you could write code like this:

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


    }

The problem with this is if your object graph has any depth you have to be sure to evict the entire set, and then you may need the originals in the session still you have to retrieve them again. This is a logistical headache and yields code with very obscure and convoluted intentions.

I do not recommend.

What is more commonly done is serialize to a binary stream and reconstitute this stream into a new set of objects. Fine, but only works if your objects are all serializable.

That is not the case for me, what I am doing is I wrote manual code to make deep copies of an object graph using copy constructors. This is complex and also can lead to maintenance issues, but if the objects cannot be serialized there are few better alternatives.

Sorry, deep copying objects remains a complicated task if serialization is not an option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文