1

NSPredicate問題は、2つのエンティティでどのように見えるかわからないことです。何か案は?

私が2つのエンティティを持っていると仮定しましょう:

Library:
1 lib_id
2 name
3 address

と:

Books
1 book_id
2 book_name
3 book_author
4 lib_id

それらの間にコアデータの関係はありません。少なくとも1冊の本を含むすべてのライブラリを含むNSArrayを返すフェッチリクエストを作成したいと思います。

私はそれがこのようなものだと思います:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescriptor *entity = [NSEntityDescriptor entityForName:@"Books" inManagedObjectContext:context];
 // some NSPredicate...
array = [context executeFetch ...];
4

3 に答える 3

8

想像以上に複雑ですが、不可能ではありません。

両方のエンティティでのデータ モデルの使用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;
}
于 2013-01-04T18:29:44.450 に答える
0

1つのフェッチ==1つのDISTINCTエンティティ。

しかし、あなたはN個の関連するエンティティを持つことができます=>1つを互いに継承させる

したがって、.. A1拡張AとA2拡張Aを持つことができます:
=> A1とA2は1つのテーブルに格納され、1回のフェッチでクエリできます(すべてのAsをフェッチ)

しかし..無関係なAとBをフェッチすることは
できません:=>1回のフェッチではフェッチできません

于 2013-01-04T20:18:09.413 に答える
0

NSFetchedResultsControllersectionNameKeyPath を使用して結果を取得するのに役立ちます。

- (id)initWithFetchRequest:(NSFetchRequest *)fetchRequest 
      managedObjectContext:(NSManagedObjectContext *)context 
        sectionNameKeyPath:(NSString *)sectionNameKeyPath 
                 cacheName:(NSString *)name;

lib_id を sectionNameKeyPath として渡すと、複数のセクションでデータが取得され、各セクションは異なる lib_id に関連付けられます。

于 2013-01-04T10:47:10.287 に答える