Ответ 1
NHibernate many-to-many
отношение действительно обеспечивает то, что мы ожидаем, позвольте мне объяснить это более подробно. Хотя нам нужны только два объекта Пользователь и Группа, нам понадобятся три таблицы: User
, Group
, UserGroup
(с столбцами UserId, GroupId)
Объекты С#:
public class User {
IList<Group> Groups {get;set;}
}
public class Group{
IList<User> Users{get;set;}
}
hbm.xml наше сопоставление будет выглядеть следующим образом:
<class name="User" ...
<bag name="Groups" lazy="true"
table="UserGroup" cascade="none" >
<key column="UserId" />
<many-to-many class="Group" column="GroupId" />
</bag>
...
<!-- and group vica versa -->
<class name="Group" ...
<bag name="Users" lazy="true"
table="UserGroup" cascade="none" >
<key column="GroupId" />
<many-to-many class="User" column="UserId" />
</bag>
...
Это сопоставление с важной установкой cascade="none"
будет выполнять ожидаемое поведение. Это сопоставление говорит о наличии PairTable UserGroup
, который не имеет представления сущности. Таким образом, не может быть никаких каскадных настроек, влияющих на эту таблицу. Эта таблица используется скрытно за сценой.
Таблица пар
Когда какой-либо пользователь удаляется, NHibernate также удалит все отношения из таблицы UserGroup
(на самом деле это будет первый оператор в пакете). Это всего лишь обработка привязки реляционных ссылок. Мы не можем оставить UserId
в таблице UserGroups
, которая не имеет своего внешнего ключа в таблице User
.
Другой конец отношения
Наконец, каскадная настройка: поскольку таблица UserGroup
управляется без нашего внимания, каскад в этом случае применяется к объекту Group
- другому концу отношения. Таким образом, установка его на all-delete-orphan может привести к полному удалению всех записей с перекрестными ссылками.
Сводка: cascade на a bag
с отношением many-to-many
предназначен для другой конечной точки, а не таблицы сопряжения.