【问题标题】:Exception deleting child records in NHibernate在 NHibernate 中删除子记录时出现异常
【发布时间】:2010-03-04 20:38:29
【问题描述】:

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

这是我的 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>
}

我将 FluentNHibernate 与 AutoMapping 结合使用。这是我的 AutoMapping 课程:

   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;
    }
}

以下是 Fluent 生成的 HBM.XML 文件:

(对于单位表):

<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>

出于单元测试的目的,我在每个存储库中都有一个“Clear()”方法,因此我可以从已知的空数据库开始。它只是做了一个

Session.Delete("from Unit");

后跟一个 Debug.Assert(Repository.GetCount() == 0);

我的问题是,当我执行 UnitsRepository.Clear() 时,我得到一个 NHibernate.ObjectDeleteException: deleted object will be re-save by cascade (remove deleted object from associations)

我已经用谷歌搜索了这个错误,并找到了一些关于它的文章,但似乎没有任何建议有效。我在父映射上添加了“.Inverse()”。我尝试将级联从“All”更改为“SaveUpdate”(它从未设置为“AllDeleteOrphans”,一些帖子将其称为问题。)我正在清除所有存储库,并尝试将整个内容包装在一个交易。我尝试在 Session.Delete 之后添加刷新。我尝试先清除父存储库,然后再清除子存储库。没有什么能摆脱错误。

任何帮助将不胜感激。

【问题讨论】:

    标签: nhibernate fluent-nhibernate exception cascade


    【解决方案1】:

    您没有在映射中显示它,但大概 Unit 引用了它的父 Contract。要删除 Unit,您必须将对 Contract 的引用设置为 null,并根据您的映射,将其从 Contract 的 Units 集合中删除。

    【讨论】:

    • Jamie,Unit POCO 或 HBM.XML 文件中都没有对合同表的引用。创建的模式确实在 Unit 表中包含一个 Contract_Id 列,我认为它来自 Contract HBM.XML 文件中的 bag/key/column name="Contract_Id" 元素。但是如果有的话,如果我只想清除所有表格怎么办?即,相当于“从单位中删除”和“从合同中删除”。我是否必须遍历 for 循环中的每个元素并删除每个元素?
    • 当您删除仍被另一个对象引用的对象时,通常会发生该错误。当 ISession 被刷新时,引用会导致被删除的对象被重新保存。由于您有 cascade=all ,因此删除合同就足够了,这将删除所有单位。
    • 我会在周一恢复工作时验证它,但我很确定我先尝试在 ContractsRepository 上调用 Clear,但仍然遇到同样的错误。
    • 好吧,这并不是我想要的答案,但显然你必须检查每个元素并单独删除它们。我找不到任何不会给出错误的 session.Delete("from ") 组合或顺序。
    猜你喜欢
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    相关资源
    最近更新 更多