Nhibernate '具有相同标识符值的不同对象'问题

本文关键字:问题 对象 Nhibernate 标识符 | 更新日期: 2023-09-27 18:17:26

我有一个更新User实体的计划进程。这个User实体与Roles对象有多对多的关系。

 public class UserMappingOverride : IAutoMappingOverride<User>
 {
    public void Override(AutoMapping<User> mapping)
    {
        mapping.HasManyToMany(u => u.Roles)
            .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.None)
            .AsSet()
            .Cascade.SaveUpdate();        
    }
 }

…其中Roles对象是UserRole实体的一个集合。

UserRole看起来像这样:

public class UserRole  : EnumEntity<UserRole.Values>
{
    public static readonly UserRole MyRole = new UserRole(Values.MyRole);
    protected UserRole(){}
    protected UserRole(Values value)
        : base(value, value.GetDescription())
    {
    }
    public enum Values
    {
        MyRole = 0
    }
}

…和用户(省略无关部分):

public class User : Entity
{
 private readonly ICollection<UserRole> roles = new HashSet<UserRole>();
 ...
  public virtual IEnumerable<UserRole> Roles
    {
        get
        {
            return roles.AsEnumerable();
        }
    }
}

作为计划过程的一部分,根据某些标准,可以在用户上添加或删除UserRole。例如

 var users = UserRepository.GetAll();
 foreach (var user in users)
 {
          var userRole =  new UserRole(0);
          user.roles.Add(userRole);
          var transaction = NHibernateSession.Current.BeginTransaction();
          try
          {
              if (transaction.IsActive)
              {
                  NHibernateSession.Current.SaveOrUpdate(user);
                  transaction.Commit();
              }
          }
          catch (Exception e)
          {
              if (transaction.IsActive)
              {
                  transaction.Rollback();
              }
          }
          finally 
          {
            NHibernateSession.Current.Close();
            NHibernateSession.Current.Dispose();
          }
  }

当进程运行时,它成功地运行到某一点,此后每次循环迭代都会产生以下结果:

  NHibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 0, of entity: MyProject.Core.Domain.UserRole
 at NHibernate.Engine.StatefulPersistenceContext.CheckUniqueness(EntityKey    key, Object obj)
所以问题是——为什么这个错误只会在某个点之后出现,我能做些什么来解决它?我已经看到在类似的问题上提到了合并,这在这里适用吗?

Nhibernate '具有相同标识符值的不同对象'问题

也许只是一个提示。

我在这里看到的重点是:

  • 现在有角色对象(只是一些enum)
  • 因此没有多对多

如果这是真的,我们将有如下的对象:

public class User : Entity
{
    ISet<UserRole> _roles = new HashSet<UserRole>();
    public virtual ISet<UserRole> Roles
    {
        get { return _roles }
    }
    ...
}

注意:我使用IList<>来维护这样的集合,我们可以在它上面创建一个虚拟只读属性,并使这个受保护的

和集合项

public class UserRole : Entity
{
    public virtual User User { get; set; }
    public RoleEnum Role { get; set; }
}

可以用HasMany(一对多)

mapping.HasMany(u => u.Roles)
    ...
    .AsSet()
    .Inverse()
    .Cascade.SaveUpdate(); 

现在就可以了,我们只需要在两端赋值

userRole.User = user;
user.Roles.Add(userRole);