我有一个更新用户实体的计划进程。此User实体与Roles对象具有ManyToMany关系。
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实体的ICollection。
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)
所以问题是 - 为什么这个错误只会在某个点之后发生,我该怎么做才能解决它?我看过Merge在类似的这类问题上提到过 - 这会适用吗?
答案 0 :(得分:0)
或许只是暗示。
我在这里看到的是:
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);