2009-06-02 10 views
32

フェッチ要求と述語を使用して、コアデータ永続ストアからオブジェクトのセットをフェッチしています。私の現在の述語は、単に属性が> =ある特定の値であるかどうかをチェックします。これは、配列内に現在保持されているオブジェクトを最終的に除外したい場合を除いて、すべて機能します。コアデータ:述語のオブジェクトIDをクエリしますか?

私は基本的にオブジェクトのセットを除外することができる必要があります、私はこれを行うことができると思う唯一の方法は、私の管理オブジェクト配列からobjectIDのリストを取得し、返されるオブジェクトに同じobjectIDが含まれないようにします。 I. @"ANY records.objectID NOT IN %@", arrayOfObjectID

どうすればいいですか?

答えて

64

フェッチ要求のエンティティは、配列内のオブジェクトの実体である

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (self IN %@)", arrayOfExcludedObjects]; 

のような述語は、あなたが欲しいものを行う必要があります。これはもちろん、フェッチ要求のために単一の述語で他の節と組み合わせることができます。

一般に、オブジェクト比較(例えば、self == %@またはself IN %@)は、コアデータクエリでobjectIDを比較します。引数は、NSManagedObjectインスタンスまたはNSMangedObjectIDインスタンスのいずれかです。したがって、上記の述語形式は、arrayOfExcludedObjectsまたは[arrayOfExcludedObjects valueForKey:@"objectID"]を引数として取ることができます。

+1

ター以下SWIFT 3溶液を投稿mは、したがって、同じような状況に直面あなたの助けのためのnks。私は[NSPredicate predicateWithFormat:@ "self not IN%@"、myArrayOfManagedObjects]を使ってみましたが、実行時にフォーマット文字列 "self not IN%@"エラーを解析できませんでした。何か案は? –

+0

申し訳ありません..投稿する前にテストしていない間違いです。私は自分の答えを修正しました( "自己NOT IN%@"の代わりに "NOT(self IN%@)"を使用してください)。 –

+0

これは私のためにうまくいった。私はそれをSQLでサポートされていない複雑なロジックを使用してフィルタリングするために使用しました。しかし、predicateWithBlockは(合理的な理由により)SQLでは動作しません。 –

9

@ BarryWarkの回答はフェッチ要求を処理するときに正しいですが、このルールをCore Data-to-Manyリレーションシップのフィルタリングに適用しようとする人に警告を出したいと思います。まもなく

:対多の関係をフィルタするときに、述語を使用した場合とINのクエリのオブジェクトのあなたの配列がたObjectIdの配列です - あなたは

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", arrayOfObjectIDs]; 
のようなクエリ文字列に self.objectIDを使用する必要があります

大文字と小文字の関係をフィルタリングする場合にちょうど(self IN %@)を使用すると、結果が不正確になるため、述語を評価してコアデータのNSManagedObjectIDのことを何も知らないNSArrayに過ぎません。

私はこれを示す特別なテストコードを作りました。申し訳ありませんが、非常に多くの行が、それはそれの価値がある。ユーザーと投稿の2つのエンティティがあり、ユーザーには「投稿」という多対多の関係があります。

User *user = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([User class]) inManagedObjectContext:managedObjectContext()]; 

Post *post = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Post class]) inManagedObjectContext:managedObjectContext()]; 

[user addPostsObject:post]; 

[managedObjectContext() save:nil]; 

// 1. Both filtered relationship array and fetch result are correct! 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self IN %@)", @[ post ]]; 

NSSet *filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
NSArray *fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

// 2. Filtered relationship array is empty (wrong), fetch result is correct, ! 
predicate = [NSPredicate predicateWithFormat:@"(self IN %@)", @[ post.objectID ]]; 

filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

// 3. Filtered relationship array is empty (wrong), fetch result is correct 
predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", @[ post ]]; 

filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

// 4. Filtered relationship array is correct, fetch result is correct 
predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", @[ post.objectID ]]; 

filteredRelationship = [user.posts filteredSetUsingPredicate:predicate]; 

fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
fetchResult = [managedObjectContext() executeFetchRequest:fetchRequest error:nil]; 

NSLog(@"\n\n\nPredicate: %@", predicate); 
NSLog(@"filteredRelationship: %@", filteredRelationship); 
NSLog(@"fetchResult: %@", fetchResult); 

TLDR出力

<redacted> Predicate: SELF IN {<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>"; })} 

<redacted> filteredRelationship: {(<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>"; }))} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 

<redacted> Predicate: SELF IN {0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1>} 

<redacted> filteredRelationship: {()} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 

<redacted> Predicate: objectID IN {<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>";})} 

<redacted> filteredRelationship: {()} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 

<redacted> Predicate: objectID IN {0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1>} 

<redacted> filteredRelationship: {(<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: { content = nil; title = nil; user = "0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>";}))} 

<redacted> fetchResult: ("<Post: 0x2a04f10> (entity: Post; id: 0x2a56c40 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/Post/p1> ; data: {\n content = nil;\n title = nil;\n user = \"0x2af2a20 <x-coredata://9D07BF41-2DC0-42C1-9DD8-6082A00E7BEB/User/p1>\";\n})") 
0

スウィフト3溶液

私は

let predicate = NSPredicate(format:"NOT (self IN %@)",[arrayofNSManagedObjects]) 
関連する問題