2009-06-02 2 views
32

Я извлекаю набор объектов из постоянного хранилища основных данных, используя запрос выборки и предикат. Мой текущий предикат просто проверяет, является ли атрибут> = определенное значение. Все это отлично работает, за исключением того, что я хочу, наконец, исключить любые объекты, которые в настоящее время хранятся в массиве.Основные данные: запрашивать идентификаторы объекта в предикате?

Я в основном должен быть в состоянии исключить набор объектов, и единственный способ, по-моему, я могу сделать это, чтобы получить список objectID из моего массива управляемых объектов и создать другое выражение в моем предикате чтобы гарантировать, что любые возвращенные объекты не имеют того же objectID. И.Е. @"ANY records.objectID NOT IN %@", arrayOfObjectID.

Как я могу это сделать?

ответ

64

Предикат как

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

где сущность запроса выборки является объектом объектов в массиве, должны делать то, что вы хотите. Разумеется, это может быть объединено с другими предложениями в одном предикате для запроса выборки.

В целом, сравнение объектов (например, self == %@ или self IN %@). Сравнить по objectID в запросах Core Data. Аргумент может быть либо экземпляром NSManagedObject , либо экземпляром NSMangedObjectID. Таким образом, формат предиката выше может принимать arrayOfExcludedObjects или [arrayOfExcludedObjects valueForKey:@"objectID"] в качестве аргумента.

+1

Того nks для вашей помощи. Я попытался использовать [NSPredicate predicateWithFormat: @ "self NOT IN% @", myArrayOfManagedObjects], но я продолжал получать «Невозможно проанализировать строку формата« self NOT IN% @ »во время выполнения. Есть идеи? –

+0

Извините .. моя ошибка за не тестирование до того, как я опубликовал. Я исправил свой ответ (используйте «NOT (self IN% @)» вместо «self NOT IN% @»). –

+0

Это сработало для меня. Я использовал его для фильтрации с использованием сложной логики, которая не поддерживается в SQL. Но predicateWithBlock не работает (по разумным причинам) на SQL. –

9

Хотя ответ @ BarryWark верен при работе с запросами на выборку, я хочу написать предупреждение для людей, которые попытаются применить это правило к фильтрации отношений Core Data to-many.

Коротко: Если при фильтрации ко-многим, которые Вы используете предикат и ваш массив объектов для запроса IN является массивом ObjectIds - то вы должны использовать self.objectID в строке запроса, как

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self.objectID IN %@)", arrayOfObjectIDs]; 

Поскольку использование только (self IN %@) в случае отношений фильтрации со многими приводит к неправильным результатам - это просто NSArray, который оценивает предикаты и ничего не знает о материалах NSManagedObjectID от Core Data.

Я разработал специальный тестовый код, показывающий это. Извините за столько строк, но они того стоят. Есть два объекта: пользователь и почта, а пользователь имеет отношение «многие» с именем «сообщения».

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

я столкнулась с той же ситуацией, поэтому я м размещением 3 быстрым решения ниже

let predicate = NSPredicate(format:"NOT (self IN %@)",[arrayofNSManagedObjects]) 
Смежные вопросы