Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort NSFetchedResultsController with object in NSSet belonging to entity

I have an object called Delivery that has a set of Customer objects associated with it. Each Delivery object also stores a mainCustomerId which is an NSNumber*. I have an NSFetchedResultsController that is used to manage the datasource for a UITableView. The issue is that I want to sort the NSFetchedResultsController by the Customer's lastName field (the customer again is stored in a many-to-many relationship called customers on the Delivery object) where one of the customers in the set has a customerId equal to the Delivery's MainCustomerId.

The Delivery Class Looks like this (only the relevant parts)

@interface Delivery : NSManagedObject
@property (nonatomic, retain) NSNumber * mainCustomerId;
@property (nonatomic, retain) NSSet *customers;
@end

The Customer Class Looks like this

@interface Customer : NSManagedObject
@property (nonatomic, retain) NSNumber * customerId;
@property (nonatomic, retain) NSString * lastName;
// And the inverse relationship to the deliveries
@property (nonatomic, retain) NSSet *deliveries;
@end

I need to make an NSSortDescriptor that does something like this (Note, I know this is the wrong format and will not work. I hope it communicates the idea though)

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"customers.AnyobjectInSet.lastName WHERE AnyobjectInSet.customerId == masterCustomerId ascending:YES];

I have tried several things using subqueries and NSExpressions but always come up short since I can't use any features that use Cocoa (like sorting with @selector) because it has to be able to generate a real mysql query with no Cocoa processing of the data. But I feel like there has to be someway to do this since it would be an easy query in mysql.

select * from Delivery JOIN Customer ON Customer.customerId=Delivery.mainCustomerId ORDER BY Customer.lastName;

I am trying to avoid having to sort after the results are fetched and store the sort order back on the object (which would be easy, but I feel it is the wrong solution since I am selecting the relevant data. There has to be a way to sort by it). Any help would be super appreciated.

Thanks in advance.

like image 765
johnrechd Avatar asked Nov 03 '22 03:11

johnrechd


1 Answers

Ok so maybe I'm missing something but the predicate suggestion makes perfect sense to me. Please correct me if I'm wrong but (assuming you know mainCustomerID):

NSNumber *mainCustomerID = ...

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"customerID == %@", mainCustomerID];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"lastName" ascending:YES];

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Customer"];
[request setPredicate:predicate];
[request setSortDescriptors:@[ sortDescriptor ]];

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request ...

So basically if its not clear, this will fetch all Customer records where customerID is equal to mainCustomerID and then sort those results by lastName. This WILL internally generate the SQL statement to perform this for you.

Is this not what you're trying to do?

Also if you want to see the SQL that is generated by CoreData at runtime (useful debugging tool), open your scheme and go to the 'Arguments' tab and add the following to 'Arguments passed at launch':

-com.apple.CoreData.SQLDebug 1

Happy Coding :)

like image 92
Shaps Avatar answered Nov 15 '22 07:11

Shaps