2012-03-14 11 views
13

少なくとも、ドキュメントで説明されている単純なケースを超えて、コアデータの関係の削除ルールがどのように機能するか少し不明です。コアデータ削除ルールが空のときに削除する

ここで質問したほとんどの答えは、1対多の関係の左側のオブジェクトが右側のオブジェクトを「所有」するモデルを使用します。 a PersonにはPhoneNumberがあり、その人物を削除すると、関連するすべての番号が削除されます。例その一種で、溶液は透明である:あなたがそうのような関係を設定した場合、Core Dataはあなたのためにすべてを処理します:私は興味がどのような

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

は反対です:どこ対多の関係「所有権」が逆転される。たとえば、CoreDataBooksサンプルコードを拡張して、ある場所でユニークな著者に関するすべての情報を収集するためのAuthorエンティティを追加することができます。 A Bookには1人の著者がいますが、著者には多くの書籍がありますが、書籍をリストしていない著者については気にしません。したがって、booksの関係が空でないAuthorの削除は許可しないでください。最後のBookを削除すると、特定のAuthorを削除すると、Authorが削除されます。

私は私がのわからないことです...これを手動で行うにはいくつかの方法を想像することができます:

  • は、Core Dataはと同じように、自動的に本の少なくとも一部を実行する方法を持っていません関係の削除ルール?
  • このような状況を処理するには、「標準的な」推奨の方法がありますか?

答えて

13

BookクラスのprepareForDeletionをオーバーライドし、他の書籍があるかどうかを確認できます。そうでない場合は、著者を削除することができます。

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

編集:冊と作者の削除を防ぐためにあなたがvalidateForDeleteまたはより良いをオーバーライドすることができます:

+2

何か他のことが起こらない限り、著者の書籍を一度に削除すると失敗するようです。私は、対応するprepareForDeletionにauthor.books.countの値を印刷しています。両方の書籍について2です。その後、著者は決して削除されません。 –

1

Rickstr、

チェック最初の場所での本で、著者でDeleteObjectのを呼び出すことはありませんあなたの2つの基準を達成するための関係については、以下を参照してください。

  1. 著者 - (拒否) - >>書籍書籍関係非空である著者を削除

DENY許されるべきではありません:関係先に少なくとも1つのオブジェクトがある場合、ソースオブジェクトは削除できません。

  1. ブック - (カスケード) - >著者

特定の著者を参照する最後のブックを削除すると、その著者

を削除する必要がありますが削除することはできません。著者は、私たちの最初のルールは、空ではない本があれば削除してはならないと言っています。それらが存在しない場合、著者は削除されます。

私は理論的にはうまくいくと思います。これがうまくいくかどうか、私に知らせてください。

+0

'著者 - (拒否) - >> Booksはいいですが、' Book - (Cascade) - > Author'は最初の著者が削除されるとすぐに著者を削除させますその著者による本は削除されます。 (どちらかまたは私は間違って何かをしています) – rickster

+0

しかし、同じ著者はDENY関係の権利とバインドされているので、彼は別の本を持っているので、理論的には削除されません。 –

1

Timのソリューションと同様に、NSManagedObjectサブクラスでwillSaveメソッドをオーバーライドできます。 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]; 
} 
関連する問題