想像以上に複雑ですが、不可能ではありません。
両方のエンティティでのデータ モデルの使用lib_id
、およびエンティティ間に Core Data 関係を追加できないというコメントは、古典的な罠に陥っていることを示唆しています。つまり、Core Data をリレーショナル データベースのように扱っています。Core Data の API は、リレーショナル データベースのようには設計されていません。そのように機能させることはできますが、Core Data を必要以上に難しくしようとしていることに注意してください。以下のソリューションが複雑に見える場合は、Core Data の処理が間違っているためです。
Core Data を本来の用途 (この場合は 2 つのエンティティ間の関係) で使用していた場合、ルックアップは簡単です。その関係Library
にエントリがなくても、すべてのフェッチを実行できます。books
そうは言っても、当面の問題は2つのステップで解決します。
まず、lib_id
のインスタンスで使用される の一意の値をすべて取得しますBooks
。以下はNSArray
、一意の値に一致する文字列を含むものを取得します。
NSFetchRequest *bookRequest = [NSFetchRequest fetchRequestWithEntityName:@"Books"];
[bookRequest setPropertiesToFetch:@[@"lib_id"]];
[bookRequest setResultType:NSDictionaryResultType];
[bookRequest setReturnsDistinctResults:YES];
NSError *error = nil;
NSArray *libIdsInBooksDicts = [[self managedObjectContext] executeFetchRequest:bookRequest error:&error];
if (libIdsInBooksDicts == nil) {
NSLog(@"Fetch error: %@", error);
return;
}
NSArray *libIdsInBooks = [libIdsInBooksDicts valueForKey:@"lib_id"];
上記の最後の行が存在するのは、libIdsInBooksDicts
実際には辞書の配列が含まれているためです。各辞書には、名前付きのキーとlib_id
実際の ID である値があります。値が必要なだけです。
次に、取得したばかりのリストにあるすべてLibrary
の人を調べます。lib_id
NSFetchRequest *libRequest = [NSFetchRequest fetchRequestWithEntityName:@"Library"];
[libRequest setPredicate:[NSPredicate predicateWithFormat:@"lib_id in %@", libIdsInBooks]];
error = nil;
NSArray *librariesWithAtLeastOneBook = [[self managedObjectContext] executeFetchRequest:libRequest error:&error];
if (librariesWithAtLeastOneBook == nil) {
NSLog(@"Fetch error: %@", error);
return;
}