Fluent NHibernate仅级联删除关联记录
我们使用NHibernate作为我们的会员系统。Fluent NHibernate仅级联删除关联记录,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我们使用NHibernate作为我们的会员系统。用户可以是多个角色的成员,而角色可以有多个用户 当删除角色或用户时,它只应级联删除关联记录(“RoleUsers”表) 删除角色的效果与预期一致。但是,删除用户不会删除关联记录,因此由于外键约束而失败 我在角色侧的映射: HasManyToMany(r => r.Users) .Access.CamelCaseField() .Table("RoleUsers")
用户
可以是多个角色
的成员,而角色
可以有多个用户
当删除角色
或用户
时,它只应级联删除关联记录(“RoleUsers”表)
删除角色
的效果与预期一致。但是,删除用户
不会删除关联记录,因此由于外键约束而失败
我在角色
侧的映射:
HasManyToMany(r => r.Users)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("RoleId")
.ChildKeyColumn("UserId")
.AsSet();
HasManyToMany(u => u.Roles)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("UserId")
.ChildKeyColumn("RoleId")
.Inverse(); // we'll add user to role, not role to user
用户
侧的映射:
HasManyToMany(r => r.Users)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("RoleId")
.ChildKeyColumn("UserId")
.AsSet();
HasManyToMany(u => u.Roles)
.Access.CamelCaseField()
.Table("RoleUsers")
.ParentKeyColumn("UserId")
.ChildKeyColumn("RoleId")
.Inverse(); // we'll add user to role, not role to user
而失败的测试是:
[Test]
public void Deleting_user_should_not_delete_roles()
{
var user = new User("john@doe.com", "John", "Doe", "Secr3t");
var role = new Role("Admin");
role.AddUser(user);
object id;
using (var txn = Session.BeginTransaction())
{
id = Session.Save(user);
Session.Save(role);
txn.Commit();
}
Session.Clear();
var fromDb = Session.Get<User>(id);
using (var txn = Session.BeginTransaction())
{
Session.Delete(fromDb);
txn.Commit();
}
Session.Query<Role>().Count().ShouldEqual(1);
}
[测试]
公共作废删除用户不应删除角色()
{
var user=新用户(“john@doe.com“,”约翰“,”多伊“,”秘书“;
var角色=新角色(“管理员”);
role.AddUser(用户);
对象id;
使用(var txn=Session.BeginTransaction())
{
id=会话。保存(用户);
Session.Save(角色);
提交();
}
Session.Clear();
var fromDb=Session.Get(id);
使用(var txn=Session.BeginTransaction())
{
删除(fromDb);
提交();
}
Session.Query().Count().ShouldEqual(1);
}
我在用户映射上尝试了
Cascade
的每一种组合,它要么失败,要么删除关联记录和角色(这不是我想要的)。反向和级联是两个不同的概念。当然,这两个都在
关系上得到了支持。请参阅文档6.8(向下滚动至6.9)
1) 首先,我们可以删除User.Roles
集合的inverse设置。这将理顺用户与角色的关系,并在用户本身被删除之前强制删除它们
2) 其次。如果用户的角色集合标记为反向
删除任何用户,将永远不会触发对的删除。这是因为我们明确地说:唯一关心这种关系的人是角色
因此,如果我们想继续您的场景:
.Inverse()//我们将用户添加到角色,而不是角色到用户
我们应该保持一致。“我们将从角色中删除用户,而不是从用户中删除角色:”
通过反向和级联,我们可以调整测试:
[Test]
public void Deleting_user_should_not_delete_roles()
{
var user = new User("john@doe.com", "John", "Doe", "Secr3t");
var role = new Role("Admin");
role.AddUser(user);
object roleId;
using (var txn = Session.BeginTransaction())
{
// I. no need to save user
roleId = Session.Save(role);
...
然后调用此命令以清除用户
...
using (var txn = Session.BeginTransaction())
{
var user = Session.Get<User>(id);
var roles = user.Roles.ToList();
roles.ForEach(role => role.RemoveUser(user))
// II. not only relations, but even the User is deleted
// becuase updated roles triggered delete orhpan
// (no Session.Update() call there)
txn.Commit();
}
。。。
使用(var txn=Session.BeginTransaction())
{
var user=Session.Get(id);
var roles=user.roles.ToList();
roles.ForEach(role=>role.RemoveUser(用户))
//二、不仅删除关系,甚至删除用户
//因为更新的角色触发了删除或HPAN
//(此处没有Session.Update()调用)
提交();
}
你的答案实际上并没有回答问题,但很接近。我问的是如何删除用户和关联,而不仅仅是关联。由于反向设置告诉NHibernate要从哪一方查找更改,答案是我们需要在删除之前从所有角色中删除要删除的用户,即user.roles.ForEach(role=>role.RemoveUser(this))
。如果您想更新您的答案,我很乐意将其标记为“更新”。不幸的是,这不符合我们的要求,因为它不支持从用户中删除角色分配。我们不应该对角色进行级联删除。事实上我自己也在回答:)
...
using (var txn = Session.BeginTransaction())
{
var user = Session.Get<User>(id);
var roles = user.Roles.ToList();
roles.ForEach(role => role.RemoveUser(user))
// II. not only relations, but even the User is deleted
// becuase updated roles triggered delete orhpan
// (no Session.Update() call there)
txn.Commit();
}