Fluent NHibernate仅级联删除关联记录

Fluent NHibernate仅级联删除关联记录,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我们使用NHibernate作为我们的会员系统。用户可以是多个角色的成员,而角色可以有多个用户 当删除角色或用户时,它只应级联删除关联记录(“RoleUsers”表) 删除角色的效果与预期一致。但是,删除用户不会删除关联记录,因此由于外键约束而失败 我在角色侧的映射: HasManyToMany(r => r.Users) .Access.CamelCaseField() .Table("RoleUsers")

我们使用NHibernate作为我们的会员系统。
用户
可以是多个
角色
的成员,而
角色
可以有多个用户

当删除
角色
用户
时,它只应级联删除关联记录(“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();
}