Reglas principales de eliminación de datos y relaciones de muchos a muchos
-
06-07-2019 - |
Pregunta
Supongamos que tiene departamentos y empleados y cada departamento tiene varios empleados, pero cada empleado también puede formar parte de varios departamentos.
Por lo tanto, existe una relación de muchos a muchos entre los empleados y los departamentos. Al eliminar un departamento, me gustaría eliminar a todos los empleados que solo forman parte de ese departamento y anular la relación con este departamento para todos los empleados que también sean miembros de otro departamento.
¿Una regla de cascada en ambas direcciones haría eso? ¿O una regla en cascada elimina automáticamente a todos los empleados de un departamento independientemente de otras afiliaciones?
Solución
Una regla de cascada eliminará automáticamente los objetos en el destino. Por lo tanto, si elimina un departamento, los empleados se eliminarán independientemente de la cantidad de departamentos en los que se encuentren.
Parece que el comportamiento que desea es un poco más matizado, para eliminar solo el " huérfano " empleados - es decir, aquellos que no tienen un departamento. Cuando eliminas un departamento, una buena manera de encontrarlos sería hacer algo como esto:
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];
Otros consejos
Gracias, Alex. Probablemente voy a hacer eso. Mientras tanto, había encontrado una forma diferente de hacer esto:
1.) registrarse para recibir notificaciones sobre cambios:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];
2.) cuando se producen cambios y se actualiza un empleado. Verifico si ese objeto tiene 0 relaciones con los departamentos y lo elimino:
- (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];
}
}
}}
Eso también funciona bien, pero podría complicarse más si tienes varias entidades diferentes para las cuales observar este tipo de comportamiento.