Combinando la condición 'Y' y 'O' en NSPnetworkingicate

De nuevo, necesito más ayuda para build mis NSPnetworkingicates 🙁

Category { name:string subs<-->>SubCategory } SubCategory { name:string numbervalue:NSNumber } 

Me gustaría saber cómo crear un pnetworkingicado con AND y OR .

Por ejemplo, me gustaría devolver todas las categorías con nombre == "category_name" que también tiene una subcategoría con un valor numérico de "valueA" OR "valueB".

He intentado cada combinación posible de constructores de pnetworkingicados con los que podría pensar pero no puedo hacerlo funcionar.

Este es mi mejor bash hasta ahora.

 NSPnetworkingicate *pnetworkingicate=[NSPnetworkingicate pnetworkingicateWithFormat@"(name== %@) AND (ANY subs.numbervalue==%@ OR ANY subs.numbervalue==%@)", @"aname", value1, value2]; 

Edit 1

Segundo bash. El filtrado en el 'numbervalue' todavía no funciona.

 NSNumber valueA=[NSNumber numberWithInt:20]; NSNumber valueA=[NSNumber numberWithInt:90]; NSArray *arr=[NSArray arrayWithObject:valueA,valueB,nil]; pnetworkingicate=[NSPnetworkingicate pnetworkingicateWithFormat:@"(name==%@)AND(ANY subs.numbervalue IN %@)",@"aname",arr]; 

Editar 2

He intentado filtrar solo por numberValue y he dejado el nombre completo.

1) al usar esto, se devuelve el set completo incluso si solo 1 elemento en el set tiene el valor.

 pnetworkingicate=[NSPnetworkingicate pnetworkingicateWithFormat:@"(ANY subs.numbervalue IN %@)",arr]; 

2) Al usar esto, se produce el mismo problema, todos los elementos del set se devuelven incluso si solo 1 de ellos coinciden.

 pnetworkingicate=[NSPnetworkingicate pnetworkingicateWithFormat:@"((SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", value1, value2]; 

También utilizando los resultados de la versión más simple en el mismo problema … no me di count de esto antes.

 NSPnetworkingicate *pnetworkingicate=[NSPnetworkingicate pnetworkingicateWithFormat@"(ANY subs.numbervalue==%@ ,valueA]; 

Entonces creo que mi problema se networkingujo.

La categoría es una entidad. SubCategory es una Entidad.

La categoría tiene una relación de uno a muchos con SubCategory y se representa como un NSSet de SubCategory.

Cada subcategoría tiene un atributo denominado numbervalue.

Edita 3

Para probar tengo 2 categorías. Ambas categorías tienen 10 subs, cada una con un valor numérico de 1 -10;

Al usar este código, ambas categorías se devuelven junto con los 10 subs para cada una.

El resultado esperado es las dos categorías devueltas, cada una con solo 2 subs.

He trazado todos mis objects y los datos son correctos. El problema es que no puedo devolver una categoría que haya filtrado subs.

 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSManagedObjectContext *context=[[DataSource shanetworkingDataSource]managedObjectContext]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context]; [fetchRequest setEntity:entity]; [fetchRequest setFetchBatchSize:20]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; NSPnetworkingicate *pnetworkingicate; NSNumber *a=[NSNumber numberWithFloat:1]; NSNumber *b=[NSNumber numberWithFloat:2]; pnetworkingicate=[NSPnetworkingicate pnetworkingicateWithFormat:@"(SUBQUERY(subs,$x,$x.numbervalue==%@ or $x.numbervalue==%@).@count> 0)",a,b]; [fetchRequest setPnetworkingicate:pnetworkingicate]; [fetchRequest setSortDescriptors:sortDescriptors]; NSError *error = nil; [NSFetchedResultsContoller deleteCacheWithName:nil]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"name" cacheName:@"Master"]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } 

Haré lo siguiente utilizando un SUBQUERY .

 [NSPnetworkingicate pnetworkingicateWithFormat@"(name == %@) AND (SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", @"aname", value1, value2]; 

Pruébalo y dímelo.

Otra solución podría ser capturar toda la colección subs y luego filtrar el set recuperado con un pnetworkingicado para verificar si los elementos coinciden con value1 o value2 .

Espero eso ayude.

Editar

Si sigue la sugerencia de Eimantas asegúrese de crear la matriz correcta:

 NSNumber valueA = [NSNumber numberWithInt:20]; NSNumber valueB = [NSNumber numberWithInt:90]; NSArray *arr = [NSArray arrayWithObjects:valueA, valueB, nil]; 

Además de la respuesta de @Stuart, puede usar NSCompoundPnetworkingicate para sus operaciones OR & Y así.

Obj-C – O

 // OR Condition // NSPnetworkingicate *pnetworkingicate1 = [NSPnetworkingicate pnetworkingicateWithFormat:@"X == 1"]; NSPnetworkingicate *pnetworkingicate2 = [NSPnetworkingicate pnetworkingicateWithFormat:@"X == 2"]; NSPnetworkingicate *pnetworkingicate = [NSCompoundPnetworkingicate orPnetworkingicateWithSubpnetworkingicates:@[pnetworkingicate1, pnetworkingicate2]]; 

Obj-C – AND

 NSPnetworkingicate *pnetworkingicate1 = [NSPnetworkingicate pnetworkingicateWithFormat:@"X == 1"]; NSPnetworkingicate *pnetworkingicate2 = [NSPnetworkingicate pnetworkingicateWithFormat:@"X == 2"]; NSPnetworkingicate *pnetworkingicate = [NSCompoundPnetworkingicate andPnetworkingicateWithSubpnetworkingicates:@[pnetworkingicate1, pnetworkingicate2]]; 

Swift – O

 let pnetworkingicate1:NSPnetworkingicate = NSPnetworkingicate(format: "X == 1") let pnetworkingicate2:NSPnetworkingicate = NSPnetworkingicate(format: "Y == 2") let pnetworkingicate:NSPnetworkingicate = NSCompoundPnetworkingicate(orPnetworkingicateWithSubpnetworkingicates: [pnetworkingicate1,pnetworkingicate2] ) 

Swift – Y

 let pnetworkingicate1:NSPnetworkingicate = NSPnetworkingicate(format: "X == 1") let pnetworkingicate2:NSPnetworkingicate = NSPnetworkingicate(format: "Y == 2") let pnetworkingicate:NSPnetworkingicate = NSCompoundPnetworkingicate(andPnetworkingicateWithSubpnetworkingicates: [pnetworkingicate1,pnetworkingicate2] ) 

Swift 3 – O

  let pnetworkingicate1 = NSPnetworkingicate(format: "X == 1") let pnetworkingicate2 = NSPnetworkingicate(format: "Y == 2") let pnetworkingicateCompound = NSCompoundPnetworkingicate.init(type: .or, subpnetworkingicates: [pnetworkingicate1,pnetworkingicate2]) 

Swift 3 – Y

  let pnetworkingicate1 = NSPnetworkingicate(format: "X == 1") let pnetworkingicate2 = NSPnetworkingicate(format: "Y == 2") let pnetworkingicateCompound = NSCompoundPnetworkingicate.init(type: .and, subpnetworkingicates: [pnetworkingicate1,pnetworkingicate2]) 

Otra opción es usar un NSCompoundPnetworkingicate (note y Pnetworkingictive With Subpnetworkingicates hace un AND, pero hay algunas opciones para usar, esto debería ser mucho más eficiente que hacer 2 búsquedas)

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCompoundPnetworkingicate_Class/index.html#//apple_ref/occ/clm/NSCompoundPnetworkingicate/andPnetworkingicateWithSubpnetworkingicates 🙂