Поддержание целостности основных объектов данных с множеством входящих связей "один ко многим"
У меня есть Базовое хранилище данных, которое содержит несколько объектов MediaItem, которые описывают, ну, в общем, элементы мультимедиа. У меня также есть NewsItems, которые имеют отношение "один ко многим" к ряду MediaItems. Все идет нормально.
Однако у меня также есть PlayerItems и GalleryItems, которые также имеют отношение один-ко-многим к MediaItems. Таким образом, MediaItems являются общими для всех сущностей.
Учитывая, что многие сущности могут иметь отношения один-ко-многим, как я могу установить взаимные отношения от MediaItem ко всем (1 или более) сущностям, которые имеют к нему отношения, и, кроме того, как я могу реализовать правила для удаления MediaItems когда число этих взаимных отношений падает до 0?
Для записи (и в случае, если это пригодится кому-то еще), я решил это, создав реферат MediaLinkedEntity
класс с отношением один ко многим MediaItems
(названный MediaItems
на MediaLinkedEntity
конец и LinkedEntities
на MediaItem
конец). Затем я подкласс этого объекта NewsItems
а также GalleryItems
и реализовал следующее -prepareForDeletion
метод в MediaLinkedEntity
:
- (void)prepareForDeletion {
NSSet *mediaItems = self.MediaItems;
NSSet *linkedEntities;
// step through all media items we link to
for( MediaItem *mediaItem in mediaItems ){
linkedEntities = mediaItem.LinkedEntities;
if( [ linkedEntities count ] == 1 && [ linkedEntities containsObject: self ] ){
// if this MediaLinkedEntity is the only entry in the mediaItem's linked entities list, delete it.
[ mediaItem.managedObjectContext deleteObject: mediaItem ];
}
}
[ super prepareForDeletion ];
}
По сути, следуя ответу Маркуса ниже.
2 ответа
Лучший ответ для этого - иметь абстрактную родительскую сущность, которая обрабатывает отношения общим способом. Это позволит вам уменьшить количество отношений в вашей модели.
Что касается правила удаления, вы должны создать подкласс для "одной" стороны отношений и реализовать их -prepareForDeletion
метод для проверки потерянных элементов на многих сторонах, а затем удалить их, когда это произойдет.
Однако у меня также есть PlayerItems и GalleryItems, которые также имеют отношение один-ко-многим к MediaItems. Таким образом, MediaItems являются общими для всех сущностей.
Самый простой, но не очень красивый способ - создать обратные отношения для каждого из отношений MediaItem.
Другой возможностью было бы создание абстрактной родительской сущности с отношением к MediaItem и наследование GalleryItem, NewsItems, PlayerItem от этой общей сущности.
Учитывая, что многие сущности могут иметь отношения один-ко-многим, как я могу установить взаимные отношения от MediaItem ко всем (1 или более) сущностям, которые имеют к нему отношения, и, кроме того, как я могу реализовать правила для удаления MediaItems когда число этих взаимных отношений падает до 0?
Есть несколько способов создать это поведение. Вы можете использовать KVO, чтобы наблюдать все обратные отношения MediaItem