0

単純な親/子テーブルがあります。コントラクトは親テーブルです。各契約は複数のユニットを持つことができます。

これが私の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>
}

AutoMappingでFluentNHibernateを使用しています。これが私の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が発生することです。削除されたオブジェクトはカスケードによって再保存されます(削除されたオブジェクトを関連付けから削除します)

私はそのエラーをグーグルで検索し、それに関する多くの記事を見つけましたが、提案されたものは何も機能していないようです。親マッピングに「.Inverse()」を追加しました。カスケードを「All」から「SaveUpdate」に変更してみました(一部の投稿で問題として引用されている「AllDeleteOrphans」に設定されていませんでした)。すべてのリポジトリをクリアし、そのすべてをラップしてみました。取引。Session.Deleteの後にフラッシュを追加してみました。最初に親リポジトリをクリアしてから、子をクリアしてみました。エラーを取り除くものは何もありません。

どんな助けでもいただければ幸いです。

4

1 に答える 1

0

マッピングには表示されませんが、おそらく Unit には親契約への参照があります。Unit を削除するには、Contract への参照を null に設定し、マッピングに応じて、Contract の Units コレクションから削除する必要があります。

于 2010-03-05T13:27:45.110 に答える