CoreData checks to see if an object-many-relationship contains an object

My application has the following data model:

data model

Basically, I want to store country names as well as city names. Each city belongs to one country, and one country contains 0 - n cities.

Before I add new cities to a specific country, I need to know if the country already contains a city with that name.

So far I am doing this:

- (BOOL)countryForName:(NSString *)countryName containsCity:(NSString *)cityName { Countries *country = [self countryForName:countryName]; NSSet *cityNames = [country valueForKey:@"cities"]; for (Cities *city in cityNames) { if ([city.cityName isEqualToString:cityName]) { return YES; } } return NO; } 

This is obviously very slow, I need an equivalent sample with the correct predicate. I do a search for a single object as follows:

  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Countries" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; // Edit the sort key as appropriate. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"countryName" ascending:YES]; NSArray *sortDescriptors = @[sortDescriptor]; fetchRequest.sortDescriptors = sortDescriptors; // Edit the section name key path and cache name if appropriate. // nil for section name key path means "no sections". NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"GetCountryList"]; aFetchedResultsController.delegate = self; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"countryName == %@", countryName]; [aFetchedResultsController.fetchRequest setPredicate:predicate]; 

But how to do this if the search includes several objects? Or, in other words: How to add unique city names for only one country?
Thank you very much!

+7
source share
1 answer

If you want to check that the given country object already contains a city with a name, you can do

 Countries *country = ... NSString *cityName = ... if ([[country valueForKeyPath:@"cities.name"] containsObject:cityName]) { // ... } 

Or, using a select query:

 NSString *countryName = ... NSString *cityName = ... NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Countries"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"countryName == %@ AND ANY cities.cityName == %@", countryName, cityName]; [fetchRequest setPredicate:predicate]; NSError *error; NSUInteger count = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error]; if (count == NSNotFound) { // error } else if (count == 0) { // no matching country } else { // at least one matching country } 

Note that a NSFetchedResultsController usually used to display the contents of a fetch query in a table, so it is not needed here.

+11
source

All Articles