Core Data, try using NSPredicate to filter the set of toMany relationships, but get the error "to-many key not allowed here"

Here is my model: http://www.girardet.ch/model.png

My goal is to get all quotes with these criteria:

  • relate to a specific topic: name_en attribute Themes
  • relevance order
  • filtered by authors (with authors alias attribute)

Here is my code:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThemeEntries" inManagedObjectContext:_context]; [fetchRequest setEntity:entity]; NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"relevancy" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil]; [fetchRequest setSortDescriptors:sortDescriptors]; // predictate - filter NSPredicate *predicate = [NSPredicate predicateWithFormat:@"theme.name_en=%@ AND quotes.author.alias=%@",@"mytheme", @"myauthor"]; 

[fetchRequest setPredicate: predicate];

I get the error "to-many key not allowed here".

If I use this predicate

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"theme.name_en=%@, @"mytheme"]; 

It works well, and I can ThemeEntries on ThemeEntries , which I get, and get all my quotes ... But it is not filtered by the authors.

What can I do to filter by authors?

+6
objective-c iphone core-data nspredicate
source share
1 answer

Your problem is that the relationship of one of your key paths is many to many, and the predicate does not know which object goes with it.

You have ThemeEntities<<-->>Quotes , which creates a set at each end. The quotes.author.alias key indicates "a set of instances of quotation marks, each of which is associated with instances of the author, which in turn has an alias attribute." The predicate cannot process the set.

You need to use a subquery to drag the key-key to many. A subquery is essentially a nested predicate that searches for a collection and returns a different set of objects matching the nested predicate. Subqueries are poorly documented, but they take the form:

 SUBQUERY(collectionName,$collectionElementVariable,expression-with-$collectionElementVariable) 

In this case, you are looking for any instances of quotes that have an author relationship with an alias corresponding to the string specified on this string. Your predicate should look like this:

 @"theme.name_en=%@ AND (0!=SUBQUERY(quotes,$eachQuote,$eachQuote.author.alias=%@) .@count )",@"mytheme", @"myauthor" 

The subquery says: "From the set of quotes, take each quotation object and check if its relationship object has an alias attribute corresponding to" myauthor. "Count the number of quotation objects with this match. Zero, return TRUE."

You need to use subqueries whenever you pave the way for a keyword through relationships with many.

+26
source share

All Articles