强制NHibernate在插入之前进行级联删除 [英] Forcing NHibernate to cascade delete before inserts

查看:93
本文介绍了强制NHibernate在插入之前进行级联删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父对象,它与子对象ISet具有一对多关系.子对象具有唯一约束(PageNumContentID-父对象的外键).

I have a parent object which has a one-to-many relationship with an ISet of child objects. The child objects have a unique constraint (PageNum and ContentID - the foreign key to the parent).

<set name="Pages" inverse="true" cascade="all-delete-orphan" access="field.camelcase-underscore">
    <key column="ContentId" />
    <one-to-many class="DeveloperFusion.Domain.Entities.ContentPage, DeveloperFusion.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</set>

我遇到的问题是,如果我从父集合中删除一个ContentPage元素,然后在同一事务中添加一个具有相同唯一键的新元素,则会出现违反唯一约束的情况,因为 NHibernate 尝试在删除之前 进行插入.

The problem I've hit is if I remove a ContentPage element from the parent collection, and then add a new one with the same unique key within the same transaction... You get a unique constraint violation because NHibernate attempts to perform the insert before the delete.

是否可以强制NHibernate首先执行删除?

Is there a way to force NHibernate to perform the delete first?

推荐答案

由于按照以下方式硬编码(根据文档),因此无法指定事务中的操作顺序:

There is no option to specify the order of operations in a transaction as it is hard-coded as follows (from the documentation):

SQL语句按以下顺序发出

The SQL statements are issued in the following order

  • 所有实体插入,都以相同的顺序使用ISession.Save()保存了相应的对象
  • 所有实体更新
  • 所有收藏夹删除
  • 所有集合元素的删除,更新和插入
  • 所有集合插入
  • 所有实体删除,以相同的顺序使用ISession.Delete()删除相应的对象
  • all entity insertions, in the same order the corresponding objects were saved using ISession.Save()
  • all entity updates
  • all collection deletions
  • all collection element deletions, updates and insertions
  • all collection insertions
  • all entity deletions, in the same order the corresponding objects were deleted using ISession.Delete()

(一个例外是,使用本机ID生成的对象会在保存时插入.)

(An exception is that objects using native ID generation are inserted when they are saved.)

这样,我可以挑战您回答为什么您要添加具有现有标识符的新实体吗?标识符对于特定的实体"应该是唯一的.如果该实体消失了,其标识符也应该消失.

As such, can I challenge you to answer why you are adding a new entity with an existing identifier? An identifier is supposed to be unique to a specific "entity." If that entity is gone, so should be its identifier.

另一种选择是对该记录进行更新,而不是删除/插入.这样可以使ID保持相同,因此(至少在键上)没有唯一的约束冲突,并且您可以更改所有其他数据,使其成为新"记录.

Another option would be to do an update on that record instead of a delete/insert. This keeps the ID the same so there is no unique constraint violation (on the key at least) and you can change all the other data so that it's a "new" record.

显然,我回答时并没有完全注意这个问题,因为这是一个对非主键列具有唯一约束的问题.

So apparently I wasn't entirely paying attention to the question when I responded since this is a problem with a unique constraint on a non-primary-key column.

我认为您有两种解决方案可供选择:

I think you have two solutions to choose from:

  1. 在删除后调用Session.Flush(),它将对会话执行所有更改,直到此刻为止,您可以继续其余操作(插入新对象).这同样适用于事务内部,因此您无需担心原子性.
  2. 创建一个ReplacePage函数,该函数使用新数据更新现有实体,但保持主键和唯一列相同.
  1. Call Session.Flush() after your delete which will execute all the changes to the session up to that point, after which you can continue with the rest (inserting your new object). This works inside of a transaction as well so you don't need to worry about atomicity.
  2. Create a ReplacePage function which updates the existing entity with new data but keeps the primary-key and the unique column the same.

这篇关于强制NHibernate在插入之前进行级联删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆