Pregunta

Estoy Recogida de una serie de objetos de un almacenamiento persistente de datos básicos utilizando una solicitud de búsqueda y un predicado. Mi predicado actual simplemente comprueba si un atributo es> = un cierto valor. Todo esto funciona muy bien, excepto que yo quiero excluir finalmente todos los objetos que se llevan a cabo actualmente en una matriz.

Yo, básicamente, que ser capaz de excluir a un conjunto de objetos, y la única forma en que pienso que puedo hacer esto es ser capaz de obtener una lista de objectID de mi serie de objetos gestionados, y crear otra expresión en mi predicado garantizar que todos los objetos devueltos no tienen la misma objectID. I.E.@"ANY records.objectID NOT IN %@", arrayOfObjectID.

¿Cómo puedo hacer esto?

¿Fue útil?

Solución

Un predicado como

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

donde la entidad de la solicitud de búsqueda es la entidad de objetos de la matriz, debe hacer lo que quiera. Esto puede, por supuesto combinarse con otras cláusulas en un solo predicado para una solicitud de búsqueda.

En general, las comparaciones de objetos (por ejemplo self == %@ o self IN %@) Compara en objectID en las consultas de la base de datos. El argumento puede ser o bien una instancia NSManagedObject o una instancia NSMangedObjectID. Por lo que el formato de predicado anterior podría tener arrayOfExcludedObjects o [arrayOfExcludedObjects valueForKey:@"objectID"] como argumento.

Otros consejos

Si bien la respuesta de @ BarryWark es correcta cuando se trabaja con ir a buscar solicitudes, quiero escribir una advertencia a las personas que tratan de aplicar esta regla a un filtrado de datos básicos a-muchas relaciones.

Poco: Si la hora de filtrar a-muchas relaciones que utiliza un predicado y su matriz de objetos para IN consulta es un conjunto de ObjectID - entonces debe usar self.objectID en la cadena de consulta como

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

Debido utilizando sólo (self IN %@) en el caso de filtración de relaciones a varios dará lugar a resultados incorrectos -. Es sólo un NSArray que evalúa los predicados y se sabe nada acerca de cosas NSManagedObjectID de datos básicos

He Construí código de prueba especial que muestra esto. Lo siento por tantas líneas, pero vale la pena. Hay dos entidades:. De usuario y Post y usuario tiene una relación de muchos-llamado "mensajes"

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);

salida 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})")
solución

Swift 3

I enfrentado la misma situación, por tanto, I m publicar una solución rápida 3 a continuación

let predicate = NSPredicate(format:"NOT (self IN %@)",[arrayofNSManagedObjects])
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top