删除抛出"已删除的对象将通过级联重新保存"

Gre*_*reg 6 c# nhibernate cascade nhibernate-mapping

我有以下型号:

<class name="Person" table="Person" optimistic-lock="version">
  <id name="Id" type="Int32" unsaved-value="0">
    <generator class="native" />
  </id>
  <!-- plus some properties here -->
</class>

<class name="Event" table="Event" optimistic-lock="version">
  <id name="Id" type="Int32" unsaved-value="0">
    <generator class="native" />
  </id>
  <!-- plus some properties here -->
</class>

<class name="PersonEventRegistration" table="PersonEventRegistration" optimistic-lock="version">
  <id name="Id" type="Int32" unsaved-value="0">
    <generator class="native" />
  </id>
  <property name="IsComplete" type="Boolean" not-null="true" />
  <property name="RegistrationDate" type="DateTime" not-null="true" />
  <many-to-one name="Person" class="Person" column="PersonId" foreign-key="FK_PersonEvent_PersonId" cascade="all-delete-orphan" />
  <many-to-one name="Event" class="Event" column="EventId" foreign-key="FK_PersonEvent_EventId" cascade="all-delete-orphan" />
</class>
Run Code Online (Sandbox Code Playgroud)

在Person和Event中都没有指向PersonEventRegistration的属性.

当我尝试从PersonEventRegistration中删除条目时,出现以下错误:

"deleted object would be re-saved by cascade"
Run Code Online (Sandbox Code Playgroud)

问题是,我不将此对象存储在任何其他集合中 - 删除代码如下所示:

public bool UnregisterFromEvent(Person person, Event entry)
{
    var registrationEntry = this.session
        .CreateCriteria<PersonEventRegistration>()
        .Add(Restrictions.Eq("Person", person))
        .Add(Restrictions.Eq("Event", entry))
        .Add(Restrictions.Eq("IsComplete", false))
        .UniqueResult<PersonEventRegistration>();

    bool result = false;
    if (null != registrationEntry)
    {
        using (ITransaction tx = this.session.BeginTransaction())
        {
            this.session.Delete(registrationEntry);
            tx.Commit();
            result = true;
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

Stu*_*lds 3

据我所知,cascade="all-delete-orphan"属于集合映射元素,而不是many-to-one. 您还没有显示映射的其他两个部分,所以我不能肯定地说,但这可能(可能)是问题所在。

我认为Person应该看起来像:

<!-- other properties -->
<set name="Events" inverse="true" cascade="all-delete-orphan">
    <key column="Person_id" />
    <one-to-many class="PersonEventRegistration" />
</set>
Run Code Online (Sandbox Code Playgroud)

Event:

<!-- similar mapping for Event -->
Run Code Online (Sandbox Code Playgroud)

PersonEventRegistration:

<!-- other properties -->
<many-to-one name="Person" class="Person" column="PersonId" foreign-key="FK_PersonEvent_PersonId" cascade="delete" <!-- or many ="all" ? --> />
Run Code Online (Sandbox Code Playgroud)

实际上,上面的可能是冲突的级联(这可能就是你所拥有的)。所以说实话,我的答案有两点:

  1. cascade="all-delete-orphan"对 没有任何意义many-to-one
  2. 确保您真正考虑过如何与实体合作以及它们应如何级联操作。

  • 你的建议很准确。这不仅仅是“‘all-delete-orphan’没有意义”。从子级到父级的级联删除通常是_邪恶的_。这就是“all”和“all-delete-orphan”在“多对一”上所做的事情。使用这些级联删除“PersonEventRegistration”将导致 NHibernate 尝试同时删除“Person”和“Event”,这肯定不是 Greg 的意图。这就是删除失败的原因 - 因为 Person 和 Event 仍然在其他地方引用,所以 NHibernate 无法删除它们。 (2认同)