I'm creating an app and trying to use core data, because it seems like it's the objective-C approved way to create a data storage system. The use case I have involves "many to many" relationships, like you'd normally see in a standard SQL system. I understand that objective C is not a database and works differently. I've also reviewed the documentation here:
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW10
And several other places. And yet, I'm still having trouble. Can someone explain to me what you would do if you have a use case where you'd need to use a SQL cross reference table? For example:
Managers | Employees
Manager may have several employees, but the employees might also have several manager. In SQL, I'd create a cross reference table and then use that.
Example: http://www.tomjewett.com/dbdesign/dbdesign.php?page=manymany.php
Can someone explain how you could do that in Core data?
According to the core data documentation, they say this:
"You define a many-to-many relationship using two to-many relationships. The first to-many relationship goes from the first entity to the second entity. The second to-many relationship goes from the second entity to the first entity. You then set each to be the inverse of the other. (If you have a background in database management and this causes you concern, don't worry: if you use a SQLite store, Core Data automatically creates the intermediate join table for you.)"
But, besides "not being worried," I don't know how this could possibly work?
Peter: "I have nine bosses, Bob." Bob: "Say again?" Peter: "Nine."
Take your brain out of the database. Do not ask how to access a cross-reference table. Ask how to find the employees for a manager or the managers for an employee.
If you use a custom subclass of NSManagedObject, you can declare the properties as documented. Then you can simply say:
NSSet *mgrsEmployees = mgr.employees; NSSet *employeesMgrs = employee.managers;
That will not give you all the employees and all the managers, only all the employees for that manager and all the managers for that employee. To change relationships:
[mgr addEmployeesObject:newEmployee]; [newEmployee addManagersObject:mgr]; // not necessary, automatic if you define inverse [mgr removeEmployeesObject:transferredEmployee]; [transferredEmployee removeManagersObject:mgr]; // not necessary [newMgr addEmployeesObject:transferredEmployee]; [transferredEmployee addManagersObject:newMgr]; // not necessary
You only need to do either one of each pair of statements, and it will implicitly do the other, provided you have defined managers and employees as inverses of each other.
If you don't use a custom subclass, accessing is a little more verbose
NSSet *mgrsEmployees = [mgr valueForKey:@"employees"]; NSSet *employeesMgrs = [employee valueForKey:@"managers"]; NSMutableSet *changeMgrsEmployees = [mgr mutableSetValueForKey:@"employees"]; [changeMgrsEmployees addObject:newEmployee]; // not necessary NSMutableSet *changeEmployeesMgrs = [employee mutableSetValueForKey:@"managers"]; [changeEmployeesMgrs addObject:mgr];
Etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With