NHibernate级联删除关联的连接子类

时间:2011-08-04 13:07:35

标签: inheritance nhibernate cascade cascading-deletes joined-subclass

我目前正在开发一个小型PoC项目,并决定将NHibernate用于持久性部分。

我已经定义了以下域实体:

  • 位置抽象类表示位置(位置树的根目录)
  • FixedLocation 抽象类,代表地理位置固定的位置(从位置派生)
  • 国家/地区:代表一个国家/地区(来自位置)
  • 城市:代表一个国家/地区内的城市(来自位置,如果没有国家/地区,则无法合理存在)

要求:

  1. 所有位置必须最终来自位置(相关地,所有位置后代将共享相同范围的数据库键)
  2. 国家/地区与城市之间应存在双向关系
  3. 删除应该在整个实体树中级联,例如删除国家/地区也应删除关联的城市
  4. 以下是我如何映射上述类

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

    以这种方式映射这些类可以满足上述要求,或者至少部分地......

    当我删除()一个国家实体(比如位置ID 1)有2个关联的城市对象(比如位置ID 2和3)时,会发生这种情况:

    1. 从国家/地区表格中删除 FixedLocationId = 1 的记录
    2. FixedLocationId = 2和3 的记录将从Cities表中删除
    3. LocationId = 1 的记录将从FixedLocations表中删除
    4. 从位置表
    5. 中删除 Id = 1 的记录

      到目前为止,这么好,但是......

      1. LocationId = 2和3 的记录 从FixedLocations表中删除
      2. Id = 2和3 的记录从位置表中删除
      3. 我在这里做错了什么?这可以在第一时间完成吗?

        我尝试在标记中设置 on-delete =“cascade”属性,但是NHibernate抱怨不允许循环级联...

1 个答案:

答案 0 :(得分:0)

不要在城市中进行多对一的级联。而是确保每个位置都知道子位置:

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

通过这种方式,您可以使层次结构和对象生命周期正常工作并正确级联。您可以在子类中考虑其他要求。