Nhibernate 一对多删除不起作用
嗨,我有一个一对多的ComplianceSet - >合规性项目。 ComplianceItem 有一个一对多的ComplianceItem ->合规性项目实例。
我有
ComplianceSet
HasMany(x => x.GetUserComplianceItems()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();
和
ComplianceItem
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等等,但无法使其工作。
请帮忙
Hi I have a one to many ComplianceSet -> ComplianceItem. ComplianceItem has a one to many ComplianceItem -> ComplianceItemInstance.
I have
ComplianceSet
HasMany(x => x.GetUserComplianceItems()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();
And
ComplianceItem
HasMany(x => x.GetUserComplianceItemInstances()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();
Then in my code I have
userComplianceSet.GetUserComplianceItems().FirstOrDefault(....);
...
userComplianceItem.RemoveUserComplianceItemInstance(userComplianceItemInstance);
this code returns
deleted object would be re-saved by cascade (remove deleted object from associations)[DecisionCritical.Core.Domain.UserComplianceSet#12]
Now this is very frustrating. If I remove the cascade from both collections the code returns success but the db show's that it didn't do anything. the ComplianceItemInstance.ComplianceItemId field is still populated and of course the item is still there.
In anycase, I just want to be able to delete a child from a collection, call save on the object holding the collection and have the freakin thing go away. I've tried all manner of permutations of cascade, save ( saving the set, saving the item ) adding delete to the ComplianceItemInstance and so and can't get this to work.
Please help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我一直在为同样的事情而苦苦挣扎。反应有点晚了,但也许未来的读者可以受益。
允许 null 作为子表上的外键的解决方案是可行的,但从数据库设计的角度来看,如果您的子表无论如何都无法在没有父表的情况下存在,那么从数据库设计的角度来看,这可能是不可取的。纯粹因为 NHibernate 需要而修改数据库设计,这不是我喜欢的事情。从双向更改为单向对我来说也是不可取的。所以我开始尝试各种映射组合。
我发现使用 inverse = true 解决了问题。首先,我认为这是 NHibernate 的不良行为,因为 inverse = true 主要被解释为让子集合负责关系,我认为我已经通过手动更新子集合和父集合来涵盖了这一点。但这种责任更多的是数据库方面的事情。
使用 inverse = true,仍然可以通过从父级中删除子级来删除子级,只要映射的父级上有 Cascade.AllDeleteOrphan,所有内容都会正确更新。如果您选择使用 Cascade.All,则还必须显式删除子级。
如果父级未加载,您还可以选择立即删除子级,只需在当前会话中删除它即可。但是,如果加载了父级,则这不起作用,在这种情况下,它将导致级联重新保存问题。
对我来说,底线是,逆向工作。我还没有找到 inverse = false 给我带来更好结果的场景,但一旦深入研究 NHibernate,我可能会回到这个观点。
I have been struggling with the same thing. Reaction is a bit late, but maybe future readers can benefit.
The solution of allowing null as foreign key on the child table works, but it might not be desirable from a database design point of view if your child cannot exist without a parent anyway. Modifying the database design purely because NHibernate requires it, is not something I prefer. Also changing from bidirectional to unidirectional was undesirable for me. So I dove in and tried all sorts of combinations of mappings.
What I found out is that using inverse = true fixed the problem. First I thought this was bad behavior from NHibernate, since inverse = true is mostly explained as making the child collection responsible for the relation, which I thought I already covered by manually updating both child and parent. But this responsibility is more of a database thing than anything else.
Using inverse = true, it is still possible to delete a child by removing it from the parent, as long as you have Cascade.AllDeleteOrphan on the parent-side of the mapping, everything will be correctly updated. If you choose to use Cascade.All, you must also explicitly delete the child.
If the parent is not loaded you can also choose to delete the child immediately, simply by deleting it in the current session. But this does not work if the parent is loaded in which case it will give the cascade re-save issues.
Bottom line for me is, inverse works. And I have not found a scenario in which inverse = false gives me better results, but I might get back to that opinion once diving deeper into NHibernate.