Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data: Fetch via specific property (join relationship)

I have an core data model as follows

alt text

The attributes property of Page is a set of DictionaryEntry, they are values for my Page objects, much like a standard NSDictionary (except all of the keys and values are strings)

I have a Page that has a DictionaryEntry with key="title" and value="Home". How would i form a fetch request to load that specific page?

like image 278
Aran Mulholland Avatar asked Feb 27 '23 05:02

Aran Mulholland


2 Answers

You should have a look at the predicate syntax for subqueries. You can not use the usual ANY keyword as this only allows you to match one column not two at the same time.

  NSString *keyValue = @"title";
  NSString *valueValue = @"home";

  NSFetchRequest *request = [[NSFetchRequest alloc] init];
  [request setEntity:[NSEntityDescription entityForName:@"Page" inManagedObjectContext:_context]];
  [request setPredicate:[NSPredicate predicateWithFormat:@"(SUBQUERY(attributes, $a, $a.key == %@ && $a.value == %@).@count != 0)", keyValue, valueValue]];

The simpler predicate ANY attributes.key = "title" AND ANY attributes.value = "home" would not work as it also returns pages that have two dicts e.g. key='addr'/value='home' and key='title'/value='pete'.

like image 135
Felix Lamouroux Avatar answered Feb 28 '23 20:02

Felix Lamouroux


Assuming you start by knowing the "key" to the DictionaryEntry of "Title".

Why don't create an NSFetchRequest on the DictionaryEntry object using your known "key" when you create an NSPredicate.

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"DictionaryEntry" inManagedObjectContext:_context]];
[request setPredicate:[NSPredicate predicateWithFormat:@"key == %@", keyValue]];

Once you have your valid DictionaryEntry object, you can then use your CoreData crufted up "page" relationship to get your valid Page.

like image 38
Daniel D Avatar answered Feb 28 '23 19:02

Daniel D