単純な親/子テーブルがあります。コントラクトは親テーブルです。各契約は複数のユニットを持つことができます。
これが私の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の後にフラッシュを追加してみました。最初に親リポジトリをクリアしてから、子をクリアしてみました。エラーを取り除くものは何もありません。
どんな助けでもいただければ幸いです。