0

私は現在、小規模な PoC プロジェクトに取り組んでおり、永続化の部分でNHibernateを試してみることにしました。

次のドメイン エンティティを定義しました。

  • Location :ロケーションを表す抽象クラス (ロケーション ツリーのルート)
  • FixedLocation :地理的に固定された場所を表す抽象クラス (Location から派生)
  • Country : 国を表します (Location から派生)
  • City : 国内の都市を表します (Location から派生し、Country なしでは論理的に存在できません)

要件:

  1. すべての場所は最終的に場所から派生する必要があります (関連して、すべての場所の子孫は同じ範囲のデータベース キーを共有します)。
  2. Country と Cityの間に双方向の関係が存在する必要があります
  3. 削除はエンティティ ツリー全体にカスケードする必要があります。たとえば、国を削除すると、関連する都市も削除されます。

上記のクラスをどのようにマッピングしたかを次に示します

    <?xml version="1.0" encoding="utf-8" ?> 
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AET.PoC.Domain" namespace="AET.PoC.Domain.Entities">    
    <class name="Location" table="Locations" abstract="true">
       <id name="Id" type="Int64" unsaved-value="0">
         <generator class="native" /> 
       </id>
       <property name="LocationType" access="readonly" /> 
    </class>
    <joined-subclass name="FixedLocation" table="FixedLocations" extends="Location" abstract="true">
         <key column="LocationId" /> 
         <component name="GPSPosition" class="GPSPosition">
             <property name="Latitude" type="double" /> 
             <property name="Longitude" type="double" /> 
         </component>
    </joined-subclass>
 <joined-subclass name="Country" table="Countries" extends="FixedLocation">
  <key column="FixedLocationId" /> 
  <property name="Name" length="50" not-null="true" /> 
 <set name="CitySet" cascade="all, delete-orphan" inverse="true">
  <key column="CountryId" foreign-key="FK_City_Country" on-delete="cascade" /> 
  <one-to-many class="City" /> 
  </set>
  </joined-subclass>
 <joined-subclass name="City" table="Cities" extends="FixedLocation">
  <key column="FixedLocationId" /> 
  <many-to-one name="Country" class="Country" column="CountryId" not-null="true" cascade="all, delete-orphan" /> 
  <property name="Name" length="50" not-null="true" /> 
  </joined-subclass>
  </hibernate-mapping>

これらのクラスをこのようにマッピングすると、上記の要件が満たされるか、少なくとも部分的に...

2 つの関連付けられた City オブジェクト (場所 ID 2 と 3 など) を持つ Country エンティティ (場所 ID 1 など)をDelete()すると、次のようになります。

  1. FixedLocationId=1のレコードがCountries テーブルから削除されます
  2. FixedLocationId=2 および 3のレコードがCities テーブルから削除されます
  3. LocationId=1のレコードがFixedLocations テーブルから削除されます
  4. Id=1のレコードがLocations テーブルから削除されます

ここまではとても良いのですが...

  1. LocationId=2 および 3のレコードは、FixedLocations テーブルから削除されませ
  2. Id=2 および 3のレコードは Locations テーブルから削除されませ

ここで何が間違っていますか?そもそもこれできるの?

タグのon-delete="cascade"属性を設定しようとしましたが、 NHibernateは循環カスケードが許可されていないと文句を言いました...

4

1 に答える 1

0

シティの多対1にカスケードを配置しないでください。代わりに、すべての場所が子の場所について知っていることを確認してください。

<class name="Location" table="Locations" abstract="true">
    ....
    <many-to-one name="_parent" column="ParentLocationID" />
    ....
    <set name="_childLocations" table="Locations" inverse="true" cascade="all-delete-orphan" >
        <key column="ParentLocationID" />
        <one-to-many class="Location"/>
    </set>
    ....
</class>

このようにして、階層とオブジェクトのライフサイクルが機能し、適切にカスケードされます。サブクラスで他の要件を取ることができます。

于 2011-08-04T13:18:39.453 に答える