2011-02-25 2 views
2

Pour une relation comme ceci:données de base avec multiples à de nombreux prédicats

TagGroups < ---- >> Balises < < ---- >> objet

Un objet a des balises, les balises peuvent être groupé par tagGroups.

J'ai un objet, et je veux connaître tous les TagGroups auxquels appartiennent ses Tags.

Pour construire il prédicats, j'ai d'abord essayé la chaîne de format suivant:

(SOI est un taggroup)

NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN SELF.tags.objects" , object]; 

Cela échoue parce que les ensembles ne sont pas traversèrent ala Key-ValueCoding.

Après quelques recherches, j'ai trouvé plusieurs questions expliquant la sous-requête

Core Data, try to use NSPredicate to filter a toMany relationship set but get the "to-many key not allowed here" error

Core data to-many NSPredicate with AND

Ceux-ci semblent faire partie de la solution, mais contrairement à ces questions, je ne suis pas à l'essai pour une valeur comme " tag.name ", mais appartenance à la collection.

Donc, avec cela à l'esprit que j'ai essayé ceci:

NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN SUBQUERY(SELF.tags, $eachTag,$eachTag.object)" , object]; 

qui ne parvient pas à analyser (j'ai essayé quelques autres variantes, sans succès, aussi bien)

Toutes les idées sur la façon de construire cette chaîne de format correctement?

Mise à jour:

également essayé de l'autre direction:

NSPredicate* p = [NSPredicate predicateWithFormat:@"ALL SUBQUERY(%@.tags,$eachTag,$eachTag.tagGroup)" , anObject]; 
+0

Je serais très surpris si CoreData pouvait traduire des expressions 'SUBQUERY' dans une instruction SQL. Je pourrais toutefois avoir tord. –

+0

Je n'étais pas au courant de cela jusqu'à ce que j'ai commencé à creuser des informations sur la récupération des relations many-to-many en utilisant NSFR. –

Répondre

0

Si vous « avez un objet », à savoir que vous avez un ManagedObject particulier dont l'entité est Object alors vous n'avez pas besoin d'un prédicat . Vous avez juste besoin de marcher le keypath de la relation.

Voici un exemple implémenté avec des dictionnaires qui fonctionne de la même manière avec un objet géré.

NSDictionary *tagGroup1=[NSDictionary dictionaryWithObjectsAndKeys:@"tagGroupOne",@"name",@"tagGroup1",@"theValue",nil]; 
NSDictionary *tagGroup2=[NSDictionary dictionaryWithObjectsAndKeys:@"tagGroupTwo",@"name",@"tagGroup2",@"theValue",nil]; 
NSDictionary *tag1=[NSDictionary dictionaryWithObject:tagGroup1 forKey:@"tagGroup"]; 
NSDictionary *tag2=[NSDictionary dictionaryWithObject:tagGroup2 forKey:@"tagGroup"]; 

NSSet *tags=[NSSet setWithObjects:tag1,tag2,nil]; 

NSDictionary *objD=[NSDictionary dictionaryWithObjectsAndKeys:tags,@"tags",nil]; 
NSLog(@"tagGroup names=%@",[objD valueForKeyPath:@"tags.tagGroup.name"]); 
NSLog(@"tagGroup objects=%@",[objD valueForKeyPath:@"tags.tagGroup"]); 

... qui sort:

tagGroup names={(
    tagGroupTwo, 
    tagGroupOne 
)} 

tagGroup objects={(
     { 
     name = tagGroupTwo; 
     theValue = tagGroup2; 
    }, 
     { 
     name = tagGroupOne; 
     theValue = tagGroup1; 
    } 
)} 

Alors, vraiment tout ce dont vous avez besoin est une ligne comme:

NSSet *tagGroups=[anInstanceOfObject valueForKeyPath:@"tags.tagGroup"]; 

C'est la puissance de codage clé-valeur.

Vous auriez seulement besoin d'une sous-requête si vous essayiez d'extraire Objects qui avait une relation avec un TagGroup avec une valeur d'attribut particulière.

+0

Merci, le problème est que j'essaie de construire un NSFetchRequest à utiliser par un NSFetchedResultsController. J'essaye de le faire pour que je n'ai pas besoin de mettre en mémoire tous les objets intermédiaires et que je puisse compter sur NSFRC pour gérer les résultats par lots. En fin de compte, j'ai fini avec une solution comme la vôtre, mais ce n'est pas idéal. Il devrait y avoir un moyen de construire correctement le SUBQUERY pour obtenir les résultats –

Questions connexes