Core Data Deletion rules and many-to-many relationships
Say you have departments and employees and each department has several employees, but each employee can also be part of several departments.
So there is a many-to-many relationship between employees and departments. When deleting a department I would like to delete all employees that are only part of that department and nullify the开发者_如何学JAVA relationship to this department for all employees that are also member of another department.
Would a cascade-rule in both directions do that? Or does a cascade rule automatically delete all employees of a department regardless of other affiliations?
A cascade rule will automatically delete the objects at the destination. So, if you delete a department, the employees will be deleted regardless of the number of departments they're in.
It sounds like the behavior you want is a little more nuanced, to delete only the "orphaned" employees -- i.e. those that don't have a department. When you delete a department, a good way of finding those would be to do something like this:
NSManagedObject *doomedDepartment = // get the department to be deleted
NSSet *employees = [doomedDepartment valueForKey:@"employees"];
NSSet *orphanedEmployees = [employees filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"departments.@count == 1"]];
for (NSManagedObject *orphanedEmployee in orphanedEmployees) {
[managedObjectContext deleteObject:orphanedEmployee];
}
[managedObjectContext deleteObject:doomedDepartment];
Thanks, alex. I will probably do that. In the meantime I had found a different way of doing this:
1.) register for notifications on changes:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];
2.) when changes occur and an employee gets updated. I check if that object has 0 relations to departments and delete it:
- (void)managedObjectContextDidChange:(NSNotification *)notification {
NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
for(NSManagedObject *obj in updatedObjects){
// walk through updated objects -> check for employees
// check if they still contain departments and if not delete them
if([obj.entity.name isEqualToString:@"Employee"]){
NSLog(@"Employee changed!");
if([[(Employee*)obj Departments] count]==0){
NSLog(@"No more relations -> Delete Employee");
[managedObjectContext deleteObject:obj];
}
}
}}
That works well too, but might get more complicated if you have several different entities for which to observe this kind of behavior.
精彩评论