NHibernate多对多,无法删除一行

Posted

技术标签:

【中文标题】NHibernate多对多,无法删除一行【英文标题】:NHibernate many-to-many, unable to delete a row 【发布时间】:2012-06-05 00:01:49 【问题描述】:

我有以下实体:Project、ProjectMapping 和 User,这是多对多的映射:

public ProjectMembershipMapping()

    Property(pm => pm.IsAccepted, prop => prop.NotNullable(true));
    Property(pm => pm.Permission, prop => prop.NotNullable(true));
    ManyToOne(pm => pm.Member, mapping =>
                                   
                                       mapping.Lazy(LazyRelation.NoLazy);
                                       mapping.Cascade(Cascade.All);
                                   );
    ManyToOne(pm => pm.Project, mapping =>
                                    
                                        mapping.Lazy(LazyRelation.NoLazy);
                                        mapping.Cascade(Cascade.All);
                                    ); 

    ComposedId(pm =>                                          
                   
                       pm.ManyToOne(prop => prop.Member);
                       pm.ManyToOne(prop => prop.Project);
                   );


public ProjectMapping()
   
    Set(proj => proj.Members,
            mapping =>
            
                mapping.Lazy(CollectionLazy.NoLazy);
                mapping.Inverse(false);
                mapping.Cascade(Cascade.All);
                mapping.Table("ProjectMembership");
                mapping.Key(k => k.Column("Project"));
            ,
            action => action.OneToMany()
        );      


public class DevcoopUserMapping : ClassMapping<DevcoopUser>

        Bag(user => user.ProjectMemberships, 
            mapping =>
                
                    mapping.Lazy(CollectionLazy.NoLazy);
                    mapping.Inverse(false);
                    mapping.Cascade(Cascade.All);
                    mapping.Table("ProjectMembership");
                    mapping.Key(k => k.Column("Member"));
                ,
            action => action.OneToMany());

用户可以是许多项目的成员。现在假设我要取消他对项目的订阅。只需通过 ISession 对象删除 ProjectMembership 对象就会抛出我:

deleted object would be re-saved by cascade (remove deleted object from associations)[devcoop.Daos.ProjectMembership#devcoop.Daos.ProjectMembership]

另一方面,当我第一次尝试从 Project 和 User 中删除这个 ProjectMembership 实例时(我按照建议从关联中删除它),我得到了异常:

could not delete collection: [devcoop.Daos.Project.Members#1][SQL: UPDATE ProjectMembership SET Project = null WHERE Project = @p0]

有人可以帮忙吗?据说我在映射周围搞砸了一些东西,但我不知道这是什么。

【问题讨论】:

我只设法通过在 3 个事务中使用 hql 查询来删除项目,这是一个混乱的解决方法,而不是解决方案。在 NHibernate 中是否有任何关于多对多的“最佳实践”,因为我显然在这些映射中搞砸了一些东西,但我找不到确切的内容 【参考方案1】:

在删除 ProjectMembership 实例之前,请将其从 DevcoopUser.ProjectMemberships- 和 Project.Members-collections 中删除。

我相信这应该可行:

  membership.Member.ProjectMemberships.Remove(membership);
  membership.Project.Members.remove(membership);
  session.Delete(membership);

我认为您应该从 ProjectMembership 映射中删除 CascadeAll。我不完全确定,但我认为它会将删除级联到使用 CascadeAll 映射的集合中的所有成员和项目,您可能不希望发生这种情况。

【讨论】:

问题是我现在得到的这些映射导致异常:无法删除集合:[devcoop.Daos.Project.Members#1][SQL: UPDATE ProjectMembership SET Project = null WHERE Project = @ p0] 正如我在问题中所写。 在您尝试删除 ProjectMembership 实例之前,您是否可以保存 User 和 Project 实体?如果是这样,请在保存用户和项目之前尝试删除 ProjectMembership。我不明白为什么 NH 会尝试更新 ProjectMembership 表。

以上是关于NHibernate多对多,无法删除一行的主要内容,如果未能解决你的问题,请参考以下文章

在 NHibernate 中定义多对多关系以允许删除但避免重复记录的正确方法是啥

多对多关系表不工作无法从中删除值

具有多对多关系的级联删除[重复]

保存循环删除多对多CoreData关系的一端

Hibernate学习笔记 — 多对多关系映射

NHibernate 和多对多映射