2010-01-05 8 views
21

Tengo tres entidades: EntityA, EntityB y EntityC conectadas con muchas relaciones.¿Cuál es la mejor manera de construir NSPredicate con muchas relaciones profundas?

Ver esquema para la descarga:

alt text http://img706.imageshack.us/img706/9974/screenshot20091220at124.png

Para conseguir toda instancia de EntityA que dependen de EntityB.name utilizo el predicado como esto:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY EntityB.name like 'SomeName'"]; 

¿Cuál debe ser predicado para conseguir todas las instancias de EntityA que dependen de EntityC.name? Intenté la consulta como @"ANY EntityB.entitiesC.name like 'SomeName'" pero obtengo la excepción "multiple to-many keys not allowed here".

Saludos,

Victor

Respuesta

12

Mi solución final es utilizar SUBQUERY.

NSPredicate *p = [NSpredicate predicateWithFormat:@"(name like %@) AND (0 != SUBQUERY(entitiesB, $x, (0 != SUBQUERY($x.entitiesC, $y, $y.name like %@)[email protected]))[email protected])", nameA, nameC]; 

Lamentablemente no pude expandir esta consulta en objetos nsExpression.

+0

¿Funciona esto con una tienda SQLite para Mac OS e iOS? De la documentación de Apple (de la biblioteca iOS 5.0: Guía de programación de datos básicos> Características persistentes de la tienda> Obtener predicciones y ordenar descriptores: puede ser diferente para Mac OS): "Hay restricciones adicionales en los predicados que puede usar con el Tienda SQLite: No necesariamente puede traducir consultas SQL "arbitrarias" en predicados. " – Dalmazio

+0

No lo he probado en Mac OS, pero para iOS funciona bien. – Victor

2

Mientras yo estaba parado en la siguiente decisión:

En primer lugar, obtener toda la EntityC que satisfacen la condición EntityC.name igual a 'somename'

NSPredicate *p = [NSPredicate predicateWithFormat:@"name like %@", @"SomeName]; 

...

NSArray *res = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

entonces consigo una serie de EntityB desde arriba consulta

NSArray *parentBs = [res valueForKeyPath:@"@distinctUnionOfObjects.parent"]; 

Que obtener variedad de EntityB que satisface la condición EntityB.EntitiesC.name igual a 'somename':

NSExpression *leftExpression = [NSExpression expressionForEvaluatedObject]; 
NSExpression *rightExpression = [NSExpression expressionForConstantValue:parentBs]; 

NSPredicate *p = [NSComparisonPredicate predicateWithLeftExpression:leftExpression rightExpression: rightExpression modifier:NSDirectPredicateModifier type:NSInPredicateOperatorType options:0]; 

repito la lo mismo para EntityA.

La efectividad de esta solución es dudosa y aún espero una mejor solución para este problema.

Cuestiones relacionadas