Подтвердить что ты не робот

Связывание ключевых данных с данными для многих, удаление при пустых

Я немного не понимаю, как работают правила удаления отношений в 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 есть способ сделать хотя бы часть этого автоматически, как с правилами удаления отношений?
  • есть ли "канонический", предпочтительный способ справиться с такой ситуацией?
4b9b3361

Ответ 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];
}