我有一个父对象,它与一个ISet
子对象有一对多的关系.子对象具有唯一约束(PageNum
以及ContentID
- 父对象的外键).
我打的问题是,如果我删除ContentPage
从父集合元素,然后添加与同一事务中相同的唯一密钥一个新的...你得到一个违反唯一约束,因为NHibernate的尝试执行插入之前的删除.
有没有办法强制NHibernate首先执行删除?
没有选项来指定事务中的操作顺序,因为它是硬编码的,如下所示(来自文档):
SQL语句按以下顺序发出
所有实体插入,使用ISession.Save()以相同的顺序保存相应的对象
所有实体更新
所有集合删除
所有集合元素删除,更新和插入
所有集合插入
所有实体删除,以相同的顺序使用ISession.Delete()删除相应的对象
(例外情况是,保存时会插入使用本机ID生成的对象.)
因此,我可以挑战您回答为什么要添加具有现有标识符的新实体吗?标识符应该对特定的"实体"是唯一的.如果该实体消失了,那么它应该是它的标识符.
另一种选择是对该记录进行更新而不是删除/插入.这使得ID保持不变,因此没有唯一的约束违规(至少在键上),您可以更改所有其他数据,使其成为"新"记录.
编辑:显然我没有完全关注我回答的问题,因为这是对非主键列的唯一约束的问题.
我认为您有两种解决方案可供选择:
Session.Flush()
删除后调用将执行到该点的所有会话更改,之后您可以继续执行其余操作(插入新对象).这也适用于事务内部,因此您无需担心原子性.
创建一个ReplacePage
函数,该函数使用新数据更新现有实体,但保持主键和唯一列相同.