Reputation: 125
Suppose a Manager
has a to-many relationship with Employee
objects. Given a reference to a Manager
object (i.e. NSManagedObject *manager
), how do I get a reference to "the Employee
with the lowest salary among all of those whose salaries exceed 10000"?
I can think of two possible approaches:
Approach 1: constructing an NSFetchRequest
and specifying the Manager
wanted with the object ID of the Manager
in question.
Approach 2: some kind of key-value coding expression on Manager
, e.g. [manager valueForKeyPath:@"..."]
(with some use of NSPredicate
?)
I'm inclined towards Approach 2 if there's a plausible solution. Please enlighten me.
Upvotes: 2
Views: 1778
Reputation: 28409
Of course, you can just apply a predicate and sort descriptor to the set returned by the relationship. Easy, and pretty quick if the set is relatively small (because it is done in memory, all the objects will have to be fetched). You may want to do that batch fetch up front to limit the number of times you do I/O.
Depending on the size of the database and the number of employees under the manager (and the indexing), you may want to do it all at the database level...
// We want "Employee" objects
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// Assuming the "inverse" relationship from employee-to-manager is "manager"...
// We want all employees that have "our" manager, and a salary > 10000
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(manager == %@) AND (salary > 10000", manager];
// Sort all the matches by salary, little-to-big
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"salary" ascending:YES]];
// Limit the returned set to 1 object, which will be the smallest
fetchRequest.fetchLimit = 1;
This will perform the entire query at the database level, and only return 1 object.
As always, performance issues are usually highly dependent on your model layout, and the options used for specifying the model and its relationships.
Upvotes: 3
Reputation: 5966
You can filter your array of Employee
relationship to get the one you want.
1) First, get all the Employee
with salaries over 10000:
NSArray *filtered = [manager.employees filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(salary > 10000)"]];
2)Then sort it in descending order
NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: @"salary" ascending: NO];
NSArray *sortedAndFiltered = [filtered sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
3)Then just get your employee
[sortedAndFiltered lastObject];
Upvotes: 1