Базовое правило удаления данных - отношение ко многим, удаление, когда пусто - PullRequest
13 голосов
/ 14 марта 2012

Я немного размышляю о том, как работают правила удаления для отношений в Core Data, по крайней мере, за исключением простых случаев, описанных в документации.

В большинстве этих случаев и в большинстве ответов, которые я видел для вопросов здесь, используется модель, в которой объект с левой стороны отношения «один ко многим» «владеет» объектами с правой стороны: например, Person имеет PhoneNumber с, и если вы удаляете человека, вы удаляете все связанные с ним номера. В таком случае решение очевидно: базовые данные будут обрабатывать все для вас, если вы установите отношения следующим образом:

Person      --(cascade)-->> PhoneNumber
PhoneNumber --(nullify)-->  Person

Что меня интересует, так это обратное: отношения «многие-многие», когда «собственность» меняется на противоположную. Например, я мог бы расширить пример кода CoreDataBooks, добавив сущность Author для сбора всей информации об уникальном авторе в одном месте. У Book есть один автор, но у автора много книг ... но нас не волнуют авторы, для которых мы не перечисляем книги. Таким образом, удаление Author, чье отношение books не является пустым, не должно быть разрешено, а удаление последнего Book, ссылающегося на конкретный Author, должно удалить это Author.

Я могу представить пару способов сделать это вручную ... в чем я не уверен:

  • У Core Data есть способ сделать хотя бы часть этого автоматически, как с правилами удаления отношений?
  • существует ли "канонический", предпочтительный способ справиться с такой ситуацией?

Ответы [ 3 ]

14 голосов
/ 14 марта 2012

Вы можете переопределить prepareForDeletion в своем классе Book и проверить, есть ли у автора другие книги.Если нет, вы можете удалить автора.

- (void)prepareForDeletion {
    Author *author = self.author;
    if (author.books.count == 1) { // only the book itself
        [self.managedObjectContext deleteObject:author];
    }
}

Редактировать: чтобы предотвратить удаление автора с книгами, вы можете переопределить validateForDelete или даже лучше: не вызывайте deleteObject с автором с книгами в первомместо

2 голосов
/ 11 октября 2012

Рикстр,

Проверьте ниже для отношений, чтобы выполнить два ваших критерия.

  1. Автор - (Deny) - >> Книги

удаление Автора, чьи отношения с книгами не пустые, не допускается

DENY: если в месте назначения отношения есть хотя бы один объект, то исходный объект удалить нельзя.

  1. Книга - (Каскад) -> Автор

удаление последней Книги, ссылающейся на конкретного Автора, должно удалить этого Автора

Вы не можете удалить автора, как гласит наше первое правило, если есть какие-то непустые книги, их не следует удалять. Если их нет, Автор удаляется.

Я думаю, теоретически это должно работать. Дайте мне знать, если это работает или нет.

1 голос
/ 16 декабря 2015

Подобно решению Тима, вы можете переопределить метод willSave в своем подклассе Author NSManagedObject. Обратите внимание, что если вы используете решение Тима, я настоятельно рекомендую фильтровать набор книг для книг, которые не были удалены; таким образом, если вы удалите все книги автора одновременно, автор все равно будет удален.

- (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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...