Я сейчас работаю над небольшим PoC-проектом и решил взять NHibernate за спин для персистентной части.
Я определил следующие доменные объекты:
- Местоположение : аннотация класс, представляющий местоположение (корень дерева местоположений)
- FixedLocation : аннотация класс, представляющий географически фиксированное местоположение (происходит от Location)
- Страна : представляет страну (происходит из Местоположения)
- Город : представляет город в стране (происходит из Местоположения и не может логически существовать без Страны)
Требования:
- Все местоположения должны в конечном итоге быть производными от Location (относительно, все потомки Location будут использовать один и тот же диапазон ключей базы данных)
- A двунаправленная связь между страной и городом должна существовать
- Удалять следует каскадно по всему дереву сущностей, например удаление страны также должно удалить связанные города
Вот как я отобразил вышеупомянутые классы
<?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>
Отображение этих классов таким образом удовлетворяет вышеуказанным требованиям или, по крайней мере, частично ...
Когда я удаляю () объект Country (скажем, идентификатор местоположения 1), который имеет 2 связанных объекта City (скажем, идентификаторы местоположения 2 и 3), это происходит так:
- Запись с FixedLocationId = 1 удаляется из таблицы стран
- Записи с FixedLocationId = 2 и 3 удаляются из таблицы городов
- Запись с LocationId = 1 удаляется из таблицы FixedLocations
- Запись с Id = 1 удаляется из таблицы Locations
Пока все хорошо, но ...
- Записи с LocationId = 2 и 3 не удалены из таблицы FixedLocations
- Записи с Id = 2 и 3 не удалены из таблицы Locations
Что я здесь не так делаю? Можно ли это сделать в первую очередь?
Я попытался установить атрибут on-delete = "cascade" в тегах, но это заставило NHibernate жаловаться на то, что круговой каскад не разрешен ...