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

发布于 2024-11-28 01:30:02 字数 2926 浏览 1 评论 0原文

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

我定义了以下域实体:

  • Locationabstract 表示位置的类(位置树的根)
  • FixedLocationabstract< /em> 代表地理位置的类(源自 Location)
  • Country:代表一个国家(源自 Location)
  • City:代表一个国家内的城市(源自 Location)并且在逻辑上不存在 所有位置最终都必须从位置

要求:

  1. 派生(相对而言,所有位置后代将共享相同范围的数据库键)
  2. 国家和城市之间应存在双向关系
  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>

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

当我删除()一个国家/地区时实体(例如位置 ID 1)有 2 个关联的 City 对象(例如位置 ID 2 和 3),会发生以下情况:

  1. 带有 FixedLocationId=1 的记录从国家表中删除
  2. 带有 FixedLocationId=2 和 3< 的记录< /em> 从 Cities 表中删除
  3. LocationId=1 的记录从固定位置表中删除
  4. Id=1 的记录从 Locations 表中删除

到目前为止,很好,但是...

  1. LocationId=2 和 3 的记录从固定位置表中删除
  2. Id=2 和 3 的记录> 是否从位置表中删除

我在这里做错了什么?首先可以做到这一点吗?

我尝试在标签中设置 on-delete="cascade" 属性,但这使得 NHibernate 抱怨不允许循环级联...

I'm currently working on a small PoC project and decided to take NHibernate for a spin for the persistence part.

I have defined the following domain entities:

  • Location: abstract class representing a location (root of the location tree)
  • FixedLocation: abstract class representing a geographically fixed location (derives from Location)
  • Country: represents a country (derives from Location)
  • City: represents a city within a country (derives from Location and cannot logically exist without a Country)

Requirements:

  1. All locations must ultimately derive from Location (relationally, all Location descendants will share the same range of database keys)
  2. A bidirectional relationship should exist between Country and City
  3. Deletes should cascade throughout the entity tree, e.g. deleting a Country should also delete the associated Cities

Here's how I mapped the above classes

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

Mapping these classes this way fullfils the above requirements, or at least partially...

When I Delete() a Country entity (say location ID 1) that has 2 associated City objects (say location IDs 2 and 3), this is what happens:

  1. The record with FixedLocationId=1 is deleted from the Countries table
  2. The records with FixedLocationId=2 and 3 are deleted from the Cities table
  3. The record with LocationId=1 is deleted from the FixedLocations table
  4. The record with Id=1 is deleted from the Locations table

So far, so good, but...

  1. The records with LocationId=2 and 3 are not deleted from the FixedLocations table
  2. The records with Id=2 and 3 are not deleted from the Locations table

What am I doing wrong here? Can this be done in the first place?

I tried setting the on-delete="cascade" attribute in the of the tags but that made NHibernate complain about circular cascading not being allowed...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴情换悲伤 2024-12-05 01:30:02

不要在 City 中进行多对一级联。相反,请确保每个位置都知道子位置:

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

这样您的层次结构和对象生命周期就可以正常工作和级联。您可以在子类中满足其他要求。

Do not put cascades on many-to-one in City. Instead make sure that every location knows about child locations:

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

This way you have your hierarchy and objects life cycle working and cascaded properly. You can take of other requirements in subclasses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文