2010-01-05 2 views
21

J'ai trois entités: EntityA, EntityB et EntityC connectées avec des relations to-many.Quoi de mieux pour construire NSPredicate avec trop de relations profondes?

Voir schéma pour plus de détails:

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

Pour obtenir toutes les instances qui dépendent de de l'Entité EntityB.name J'utilise le prédicat comme ceci:

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

Quel devrait être prédicats pour obtenir toute instance de EntityA qui dépend de EntityC.name? J'ai essayé requête comme @"ANY EntityB.entitiesC.name like 'SomeName'" mais obtenir l'exception "multiple to-many keys not allowed here".

Meilleures salutations,

Victor

Répondre

12

Ma solution finale est d'utiliser 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]; 

Malheureusement, je n'ai pas pu développer cette requête sur les objets nsExpression.

+0

Est-ce que cela fonctionne avec un magasin SQLite pour Mac OS et iOS? La documentation Apple (de la bibliothèque iOS 5.0: Guide de programmation des données de base> Fonctions de stockage permanentes> Récupérer les prédicats et les descripteurs de tri) peut être différente pour Mac OS: "Il existe des contraintes supplémentaires sur les prédicats que vous pouvez utiliser avec Banque SQLite: Vous ne pouvez pas nécessairement traduire les requêtes SQL "arbitraires" en prédicats. " – Dalmazio

+0

Je ne l'ai pas testé sous Mac OS mais pour iOS son fonctionnement est correct. – Victor

2

Pendant que j'été arrêté à la décision suivante:

D'abord, je reçois tous les EntityC qui satisfont la condition EntityC.name égale à 'UnNom'

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

...

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

Puis-je obtenir un tableau de requête ci-dessus de l'Entité

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

que d'obtenir tableau de qui satisfont la Entité B état EntityB.EntitiesC.name égal à « UnNom »:

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

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

Je répète la même chose pour EntityA.

L'efficacité de cette solution dans le doute et je m'attends toujours à une meilleure solution pour ce problème.

Questions connexes