我目前正在从事一个小型 PoC 项目,并决定将NHibernate用于持久性部分。
我定义了以下域实体:
- Location :表示位置的抽象类(位置树的根)
- FixedLocation:表示地理固定位置的抽象类(派生自 Location)
- Country : 代表一个国家(来自 Location)
- City : 代表一个国家内的城市(从 Location 派生,没有 Country 就不能在逻辑上存在)
要求:
- 所有位置最终都必须从位置派生(相对而言,所有位置后代将共享相同范围的数据库键)
- Country和City之间应该存在双向关系
- 删除应该在整个实体树中级联,例如删除一个国家也应该删除关联的城市
这是我映射上述类的方式
<?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>
以这种方式映射这些类满足了上述要求,或者至少部分......
当我Delete()具有 2 个关联城市对象(例如位置 ID 2 和 3)的国家实体(例如位置 ID 1)时,会发生以下情况:
- FixedLocationId=1的记录从国家表中删除
- 从 Cities 表中删除FixedLocationId=2 和 3的记录
- LocationId=1的记录从 FixedLocations 表中删除
- 从 Locations 表中删除Id=1的记录
到目前为止,一切都很好,但是...
- LocationId=2 和 3的记录不会从 FixedLocations 表中删除
- Id=2 和 3的记录不会从 Locations 表中删除
我在这里做错了什么?这可以首先完成吗?
我尝试在标签中设置on-delete="cascade"属性,但这让NHibernate抱怨不允许循环级联......