Связывание ключевых данных с данными для многих, удаление при пустых
Я немного не понимаю, как работают правила удаления отношений в Core Data, по крайней мере, за пределами простых случаев, описанных в документации.
Большинство из этих случаев и большинство ответов, которые я видел для вопросов здесь, используют модель, где объект на левой стороне отношения "один ко многим" "владеет" объектами с правой стороны: например. a Person
имеет PhoneNumber
s, и если вы удаляете человека, вы удаляете все связанные с ним номера. В этом случае решение понятно: Core Data будет обрабатывать все для вас, если вы установите такие отношения следующим образом:
Person --(cascade)-->> PhoneNumber
PhoneNumber --(nullify)--> Person
Меня интересует противоположность: отношения "ко многим", в которых "собственность" отменяется. Например, я мог бы расширить пример кода CoreDataBooks, чтобы добавить объект Author
для сбора всей информации об уникальном авторе в одном месте. A Book
имеет одного автора, но у автора много книг... но нас не интересуют авторы, для которых мы не перечисляем книги. Таким образом, удаление Author
, отношение books
не должно быть пустым, не должно быть разрешено, а удаление последнего Book
, ссылающегося на конкретный Author
, должно удалить это Author
.
Я могу представить пару способов сделать это вручную... что я не уверен в следующем:
- У Core Data есть способ сделать хотя бы часть этого автоматически, как с правилами удаления отношений?
- есть ли "канонический", предпочтительный способ справиться с такой ситуацией?
Ответы
Ответ 1
Вы можете переопределить prepareForDeletion
в своем классе Book
и проверить, есть ли у автора какие-либо другие книги. Если нет, вы можете удалить автора.
- (void)prepareForDeletion {
Author *author = self.author;
if (author.books.count == 1) { // only the book itself
[self.managedObjectContext deleteObject:author];
}
}
Изменить: во избежание удаления автора с книгами вы можете переопределить validateForDelete
или даже лучше: не вызывайте deleteObject с автором с книгами в первую очередь
Ответ 2
Рикстр,
Проверьте, чтобы отношения были выполнены, чтобы выполнить два ваших критерия.
-
Автор - (Запрет) → > Книги
удаление автора, отношения между книгами которого не являются пустыми, не должно быть разрешено
DENY: Если в назначении отношения есть хотя бы один объект, исходный объект не может быть удален.
удаление последней книги, ссылающейся на конкретного автора, должно удалить этот автор
Вы не можете удалить автора, как говорится в нашем первом правиле, если какие-либо Книги, которые не являются пустыми, не должны быть удалены. Если они отсутствуют, автор удаляется.
Я думаю, что теоретически он должен работать. Дайте мне знать, если это работает или нет.
Ответ 3
Аналогично решению Tim вы можете переопределить метод willSave
в подклассе Author NSManagedObject
. Обратите внимание, что если вы используете решение Tim, я настоятельно рекомендую фильтровать книги, установленные для книг, которые не были удалены; таким образом, если вы одновременно удалите все авторские книги, автор все равно будет удален.
- (void)willSave {
if (!self.isDeleted) {
NSPredicate *notDeletedPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary<NSString *,id> *bindings) {
return ![(NSManagedObject *)evaluatedObject isDeleted];
}];
NSSet *filteredBooks = [self.books filteredSetUsingPredicate:notDeletedPredicate];
if (filteredBooks.count == 0)
[self.managedObjectContext deleteObject:self];
}
[super willSave];
}