删除NHibernate中的子记录时出现异常

删除NHibernate中的子记录时出现异常,nhibernate,fluent-nhibernate,exception,cascade,Nhibernate,Fluent Nhibernate,Exception,Cascade,我有一个简单的父/子表。合同是父表。每个合同可以有多个单元 以下是我的C类简化定义: public class Contract : EntityWithIntID { public virtual string ContractNum { get; set; } public virtual IList<Unit> Units { get; protected set; } public virtual int NumberOfUnits {

我有一个简单的父/子表。合同是父表。每个合同可以有多个单元

以下是我的C类简化定义:

    public class Contract : EntityWithIntID
{
    public virtual string ContractNum { get; set; }
    public virtual IList<Unit> Units { get; protected set; }
    public virtual int NumberOfUnits
    {
        get { return Units.Count; }
    }
 }

    public class Unit : EntityWithIntID
{
    <various Unit physical data fields>
}
后跟Debug.AssertRepository.GetCount==0

我的问题是,当我执行UnitsRepository.Clear时,会得到一个NHibernate.ObjectDeleteException:已删除的对象将通过级联重新保存从关联中删除已删除的对象

我在谷歌上搜索了这个错误,并找到了许多关于它的文章,但似乎没有任何建议起作用。我在父映射上添加了.Inverse。我曾尝试将级联从All更改为SaveUpdate,但从未将其设置为AllDelete孤儿,一些帖子称这是问题所在。我正在清理所有的存储库,并尝试将整个内容包装到一个事务中。我尝试在会话后添加刷新。删除。我尝试先清除父存储库,然后清除子存储库。没有什么能消除这个错误


任何帮助都将不胜感激。

您在映射中没有显示它,但单元可能有其父合同的引用。要删除单位,您必须将对合同的引用设置为null,并根据您的映射,将其从合同的单位集合中删除。

Jamie,单位POCO或HBM.XML文件中都没有对合同表的引用。创建的模式在Unit表中包含一个Contract_Id列,我认为它来自Contract HBM.XML文件中的bag/key/column name=Contract_Id元素。但是如果有,如果我只想清理所有的桌子呢?即,执行从单位中删除和从合同中删除的等效操作。我是否必须遍历for循环中的每个元素并删除每个元素?当删除仍由另一个对象引用的对象时,通常会发生此错误。刷新ISession时,引用会导致重新保存已删除的对象。既然你有cascade=all,那么删除合同就足够了,这将删除所有的单位。我会在周一回去工作时进行验证,但我很确定我先打电话询问了合同回复,但我仍然收到了相同的错误。嗯,这并不是我想要的答案,但显然,您必须遍历每个元素并分别删除它们。我找不到会话的任何组合或顺序。Deletefrom不会给出错误。
   public static AutoPersistenceModel GetMappings()
    {
        AutoPersistenceModel returnModel = AutoMap.AssemblyOf<Contract>()
            .IgnoreBase(typeof(EntityWithIntID))
            .Where(type => type.BaseType == typeof(EntityWithIntID) )
            .Conventions.Add(typeof(PluralTableNamesConvention))
            .Conventions.Add(typeof(CascadeAllConvention))
            .Override<Contract>(map =>map.HasMany(cont =>cont.Units).Inverse())
            .Override<Contract>(map=>map.Map(cont => cont.ContractNum).Not.Nullable().Unique())
        ;
        return returnModel;
    }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" name="InterfaceDB.Unit, InterfaceDB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Units">
   <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="hilo">
        <param name="max_lo">10</param>
      </generator>
   </id>
<!-- physical data property elements removed for brevity -->
  </class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="InterfaceDB.Contract, InterfaceDB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Contracts">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="hilo">
        <param name="max_lo">10</param>
      </generator>
    </id>
    <property name="ContractNum" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ContractNum" not-null="true" unique="true" />
    </property>
    <bag cascade="all" inverse="true" name="Units">
      <key>
        <column name="Contract_id" />
      </key>
      <one-to-many class="InterfaceDB.Unit, InterfaceDB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
  </class>
</hibernate-mapping>
Session.Delete("from Unit");