Что вы говорите здесь:
Единственный способ успешно удалить роль - это запросить все артефакты, связанные с этой ролью, удалить роль из коллекции ролей артефакта, обновить артефакты и затем удалить роль - не очень эффективно или красиво, особенно когда в В упрощенной системе роли могут быть связаны с любым количеством других таблиц / объектов.
Не обязательно. Предположим, что вы не хотите отображать таблицу ассоциации (сделать ее объектом домена), вы все равно можете выполнять удаление на обоих концах с минимальным кодом.
Допустим, есть 3 таблицы: Role, Artifact и ArtifactAccess (таблица ссылок).
В вашем отображении у вас есть только доменные объекты для роли и артефакта. У обоих есть сумка для ассоциации многих-многих.
Роль:
<bag name="Artifacts" table="[ArtifactAccess]" schema="[Dbo]" lazy="true"
inverse="false" cascade="none" generic="true">
<key column="[ArtifactID]"/>
<many-to-many column="[RoleID]" class="Role" />
</bag>
Артефакт:
<bag name="Roles" table="[ArtifactAccess]" schema="[Dbo]" lazy="true"
inverse="false" cascade="none" generic="true">
<key column="[RoleID]"/>
<many-to-many column="[ArtifactID]" class="Role" />
</bag>
Как видите, на обоих концах указано обратное = false. Документация NHibernate рекомендует вам выбрать один конец вашей ассоциации в качестве «обратного» конца, но ничто не мешает вам использовать оба в качестве «контрольного конца». При выполнении обновлений или вставок это работает в обоих направлениях без помех. При выполнении удалений любого из концов вы получаете ошибку нарушения FK, поскольку таблица ассоциации не обновляется, true. Но вы можете решить эту проблему, просто очистив коллекцию на другом конце, перед выполнением удаления, которое намного менее сложно, чем то, что вы делаете, которое выглядит в «другом» конце ассоциации, если есть варианты использования этого ' конец. Если это немного сбивает с толку, вот пример кода. Если у вас есть только один конец контроля, для сложного удаления вам нужно сделать:
foreach(var artifact in role.Artifacts)
foreach(var role in artifact.Roles)
if(role == roleToDelete)
artifact.Roles.Remove(role)
artifact.Save();
roleToDelete.Delete();
Что я делаю, когда удаляю роль, что-то вроде
roleToDelete.Artifacts.Clear(); //removes the association record
roleToDelete.Delete(); // removes the artifact record
Это одна дополнительная строка кода, но таким образом вам не нужно принимать решение о том, какой конец ассоциации является обратным. Вам также не нужно отображать таблицу ассоциации для полного контроля.