gpt4 book ai didi

c# - 如何正确更新 NHibernate 多对多与 Transient 对象的关系? transient 对象异常

转载 作者:太空宇宙 更新时间:2023-11-03 14:00:34 27 4
gpt4 key购买 nike

我在尝试保存属于多对多关联的对象时收到 TransientObjectException。我有点理解为什么会这样,但想了解如何正确完成我正在尝试做的事情。

简而言之,我正在尝试做的事情:

我的应用程序有一个用户列表和一个角色列表。用户可以分配给多个角色,角色可以分配给多个用户。有一个网页,管理员可以在其中执行这些分配,分配可以双向完成(例如,管理员可以选择一个用户,然后向其添加角色;或者,选择一个角色并向其添加用户)。

例如,假设管理员点击了用户“Alice”的“编辑”。管理员会看到可用角色列表和已分配给 Alice 的角色列表。然后管理员为 Alice 分配一个新角色并点击“保存”。

在服务器上,从客户端接收临时用户和分配的角色对象。如果我只是将临时角色列表分配给用户对象(例如,user.Roles = roles),我就可以很好地更新。但是,如果我在进行此分配之前碰巧从数据库中读取了 User,则会在关联的 Role 对象上得到 TransientObjectException。

类定义:

public class Role
{
public Guid ID { get; set; }
public virtual IList<User> Users { get; set; }
}

public class User
{
public Guid ID { get; set; }
public virtual IList<Role> Roles { get; set; }
}

映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Role">
<id name="ID">
<generator class="guid"/>
</id>

<bag name="Users" table="Role_User" lazy="false" cascade="none">
<key column="RoleID" />
<many-to-many column="UserID" class="User" />
</bag>
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="User">
<id name="ID">
<generator class="guid"/>
</id>

<bag name="Roles" table="Role_User" lazy="false" cascade="none">
<key column="UserID" />
<many-to-many column="RoleID" class="Role" />
</bag>
</class>
</hibernate-mapping>

要保存的代码(有效)

public void UpdateUser(User user, IList<Role> associatedRoles)
{
using (var session = _sessionFactory.OpenSession())
{
user.Roles = associatedRoles;
session.Merge<User>(user);
}
}

要保存的代码(失败)

public void UpdateUser(User user, IList<Role> associatedRoles)
{
using (var session = _sessionFactory.OpenSession())
{
User originalUser = session.Get<User>(user.ID);
// Code that does some audit reporting/logging
LogDifferences(originalUser, user);
user.Roles = associatedRoles;
session.Merge<User>(user);
}
}

对象是一个未保存的 transient 实例 - 在合并之前保存 transient 实例

最佳答案

Jouni Aro 是对的......你不能在你的 session 中有两个具有相同 ID 的实体实例。

问题是以下之一:

  1. 您正在尝试从数据库加载 originalUser,但 user 已附加到同一 session
  2. 您已经加载了 originalUser,然后尝试将 user 合并到同一个 session - 按照 Jouni 的建议,首先驱逐 originalUser

无论如何,您真的需要加载原始用户来了解更改内容吗?使用 NHibernate 还有其他方法可以做到这一点。你试过了吗interceptors

这是一种潜在的用法:http://nhforge.org/wikis/howtonh/finding-dirty-properties-in-nhibernate.aspx . Google多一点。

关于c# - 如何正确更新 NHibernate 多对多与 Transient 对象的关系? transient 对象异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10819567/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com