I’m sadly stuck with Core data. I’ve built a 1:M relationship, let’s say Company and Employees.
I create the Company, then I create the Employee:
Employees *employee = (Employees *)[NSEntityDescription insertNewObjectForEntityForName:@"Employees" inManagedObjectContext:myObjectContext];
employee.name = employeeName;
employee.company = company;
NSError *error = nil;
if (![myObjectContext save:&error])
{
// Handle the error.
NSLog(@"error: %@", error.description);
}
If I analyze the sql file, I can see that the Parent column for the Employees record is correctly populated with the Company identifier.
Now I would like to select a Company in my tableview and show its Employees in another tableview. I implement the NSFetchedResultsController as follows:
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController != nil)
{
return fetchedResultsController;
}
//retrieve context
if (myObjectContext == nil)
{
id appDelegate = (id)[[UIApplication sharedApplication] delegate];
self.myObjectContext = [appDelegate managedObjectContext];
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employees" inManagedObjectContext:myObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *myFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:myObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
self.fetchedResultsController = myFetchedResultsController;
fetchedResultsController.delegate = self;
return fetchedResultsController;
}
and I call it in viewDidAppear:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSError *error = nil;
//call the fetch
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(@"Error with fetchedResultsController: %@, %@", error, [error userInfo]);
exit(-1);
}
[self.tableView reloadData];
}
The problem is that all the Employees, and not only those in the selected Company, are displayed.
Any ideas?
Your fetch request is setup to fetch all employees with no condition so just as you are seeing, you are going to get all employees in your database. You either need to set a predicate on your fetch request using
NSPredicateand have it only select Employees whose Company is the company you selected in the previous view. Or, the approach I would take, you have the Company object selected, pass its managedObjectId or the managedObject itself to your Employee tableview controller and use the relationship you setup to fetch the employees from it, Core Data will fill in any faults and fetch the related employee objects from the database for you.If you setup your relationship properly calling
selectedCompany.employeeswill return an NSSet which you can use as yourUITableViewController‘s data source.Edit
If there are potentially a large number of employees in the relationship you may want to stick with the fetched results controller approach and setup the predicate appropriately in order to obtain the memory efficiency benefits that
NSFetchedResultsControllerbrings to the table.