2010-01-05 15 views
21

Ho tre entità: EntityA, EntityB ed EntityC connesse con le relazioni to-many.Qual è il modo migliore per creare NSPredicate con molte relazioni profonde?

Vedere schema per i dettagli:

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

Per ottenere tutte le istanze di EntityA che dipendono da EntityB.name Io uso il predicato in questo modo:

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

Quale dovrebbe essere predicato per ottenere tutte le istanze di EntityA che dipendono da EntityC.name? Ho provato query come @"ANY EntityB.entitiesC.name like 'SomeName'" ma ottengo l'eccezione "multiple to-many keys not allowed here".

Con i migliori saluti,

Victor

risposta

12

La mia soluzione finale è l'uso di 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]; 

Purtroppo non è stato possibile espandere questa query sugli oggetti nsExpression.

+0

Funziona con uno store SQLite sia per Mac OS che per iOS? Dalla documentazione di Apple (dalla libreria iOS 5.0: Guida alla programmazione Core Data> persistenti Caratteristiche dei negozi> Fetch predicati e ordinamento descrittori - può essere diverso per Mac OS): "Ci sono ulteriori vincoli sui predicati che è possibile utilizzare con il negozio SQLite: non si può necessariamente tradurre le query SQL “arbitrari” in predicati ". – Dalmazio

+0

Non l'ho testato su Mac OS ma per iOS funziona bene. – Victor

2

Mentre ero fermato al seguente decisione:

In primo luogo, ho tutto l'EntityC che soddisfano la condizione di EntityC.name uguale a 'SomeName'

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

...

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

allora ottengo un array di EntityB dall'alto interrogazione

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

che ottenere array di EntityB che soddisfano la condizione EntityB.EntitiesC.name uguale a 'SomeName':

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

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

ripeto la lo stesso per EntityA.

L'efficacia di questa soluzione è in dubbio e mi aspetto ancora una soluzione migliore per questo problema.

Problemi correlati