2012-10-05 45 views
6

Configuración: Tengo una colección de objetos principales, llámalos ObjectA. Cada ObjectA tiene una relación de uno a muchos con ObjectB. Entonces, un ObjectA puede contener 0..n ObjectB-s, y cada ObjectB tiene un ObjectA específico como su padre.¿Cómo ordenar los resultados de Datos básicos según un atributo de la colección de objetos relacionados?

Ahora, me gustaría hacer una búsqueda de datos básicos de ObjectA-s, donde se ordenan por su último ObjectB. ¿Es posible crear un descriptor de clasificación para eso?

Hay a related question que describe exactamente la misma situación. La respuesta sugiere desnormalizar el atributo de ObjectB en ObjectA. Esto estaría bien si realmente no hay manera de hacer esto con una solicitud de búsqueda.

La pregunta relacionada también menciona:

Actually, I just had an idea! Maybe I can sort Conversations by [email protected]

lo intentara. No parece ser posible. Obtengo este error:

2012-10-05 17:51:42.813 xxx[6398:c07] *** Terminating app due to uncaught 
exception 'NSInvalidArgumentException', reason: 'Keypath containing 
KVC aggregate where there shouldn't be one; failed to handle 
[email protected]' 

¿Es la desnormalización del atributo en ObjectA la única/mejor solución?

Respuesta

0

Se podría añadir un atributo en ObjectB que es la marca de tiempo de la fecha de complemento, a continuación, en la solicitud de búsqueda se puede hacer algo como esto:

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"objectB.addTime" ascending:YES]; 
... 
fetchRequest.sortDescriptors = @[descriptor]; 
+2

Esto no funcionó para mí: 'NSInvalidArgumentException', razón: 'muchas claves no permitidas aquí' –

0

Sé que esta pregunta es un poco viejo, pero lo Lo que hice fue obtener todos los ObjectB, iterar sobre los resultados y extraer la propiedad ObjectB y agregarla a una nueva matriz.

NSFetchRequest *fetchRequest = [NSFetchRequest new]; 
[fetchRequest setEntity:self.entityDescForObjectB]; 

// sort 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES]; 
[fetchRequest setSortDescriptors:@[sortDescriptor]]; 

NSError *error = nil; 
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
if (fetchedObjects == nil) { 
    NSLog(@"Error fetching objects: %@", error.localizedDescription); 
    return; 
} 

// pull out all the ObjectA objects 
NSMutableArray *tmp = [@[] mutableCopy]; 
for (ObjectB *obj in fetchedObjects) { 
    if ([tmp containsObject:obj.objectA]) { 
     continue; 
    } 
    [tmp addObject:obj.objectA]; 
} 

Esto funciona porque CoreData es un gráfico de objetos para que pueda trabajar hacia atrás. El bucle al final básicamente verifica si la matriz tmp ya tiene una instancia específica de ObjectA y si no la agrega a la matriz.

Es importante que ordene los ObjectB, de lo contrario, este ejercicio no tiene sentido.

Cuestiones relacionadas