2

嗨,我有一个一对多的 ComplianceSet -> ComplianceItem。ComplianceItem 有一个一对多的 ComplianceItem -> ComplianceItemInstance。

我有

合规集

HasMany(x => x.GetUserComplianceItems()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();

合规项目

HasMany(x => x.GetUserComplianceItemInstances()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();

然后在我的代码中

userComplianceSet.GetUserComplianceItems().FirstOrDefault(....); ... userComplianceItem.RemoveUserComplianceItemInstance(userComplianceItemInstance);

此代码返回

级联将重新保存已删除的对象(从关联中删除已删除的对象)[DecisionCritical.Core.Domain.UserComplianceSet#12]

现在这非常令人沮丧。如果我从两个集合中删除级联,则代码返回成功,但数据库显示它没有做任何事情。ComplianceItemInstance.ComplianceItemId 字段仍然填充,当然该项目仍然存在。无论如何,我只想能够从集合中删除一个孩子,对持有该集合的对象调用 save 并让这该死的东西消失。我已经尝试了级联的各种排列方式,保存(保存集合,保存项目)将删除添加到 ComplianceItemInstance 等等,但无法让它工作。

请帮忙

4

1 回答 1

1

我一直在为同样的事情而苦苦挣扎。反应有点晚,但也许未来的读者可以受益。

允许 null 作为子表上的外键的解决方案有效,但从数据库设计的角度来看,如果您的孩子无论如何都不能在没有父母的情况下存在,那么这可能是不可取的。纯粹因为 NHibernate 需要而修改数据库设计,这不是我喜欢的。从双向更改为单向对我来说也是不可取的。所以我潜入并尝试了各种映射组合。

我发现使用 inverse = true 解决了这个问题。首先,我认为这是 NHibernate 的不良行为,因为 inverse = true 主要被解释为使子集合负责关系,我认为我已经通过手动更新子集合和父集合来涵盖了这一点。但是这个责任更多的是数据库的事情而不是其他任何事情。

使用 inverse = true,仍然可以通过从父级中删除子级来删除它,只要映射的父级有 Cascade.AllDeleteOrphan,一切都会正确更新。如果您选择使用 Cascade.All,您还必须显式删除子项。

如果未加载父级,您也可以选择立即删除子级,只需在当前会话中删除它即可。但是,如果加载了父级,则这不起作用,在这种情况下,它将给级联重新保存问题。

对我来说,底线是逆向作品。而且我还没有找到 inverse = false 给我带来更好结果的场景,但是一旦深入研究 NHibernate,我可能会回到那个观点。

于 2012-04-03T13:23:59.737 回答