Core Data Supressão regras e muitos-para-muitos relacionamentos
-
06-07-2019 - |
Pergunta
Digamos que você tenha departamentos e funcionários e cada departamento tem vários funcionários, mas cada funcionário também pode ser parte de vários departamentos.
Portanto, há um relacionamento muitos-para-muitos entre funcionários e departamentos. Ao excluir um departamento gostaria de apagar todos os funcionários que são apenas uma parte desse departamento e anular a relação a este departamento para todos os funcionários que são também membro de outro departamento.
Será que uma cascata-regra em ambas as direções fazer isso? Ou será que uma regra de exclusão em cascata automaticamente todos os funcionários de um departamento independente de outras afiliações?
Solução
Uma regra cascata vai eliminar automaticamente os objetos no destino. Então, se você excluir um departamento, os funcionários serão eliminados, independentemente do número de departamentos que eles estão em.
Parece que o comportamento que você quer é um pouco mais matizada, para excluir apenas os "órfãos" funcionários - ou seja, aqueles que não têm um departamento. Ao excluir um departamento, uma boa maneira de encontrar aqueles seria fazer algo como isto:
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];
Outras dicas
Obrigado, Alex. Eu provavelmente vou fazer isso. Nesse meio tempo eu tinha encontrado uma maneira diferente de fazer isso:
1) registrar para notificações sobre alterações:.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];
2.) Quando ocorrem alterações e um empregado é atualizado. I verificar se esse objeto tem 0 relações com os departamentos e excluí-lo:
- (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];
}
}
}}
Isso funciona muito bem, mas pode ficar mais complicado se você tiver várias entidades diferentes para que observar este tipo de comportamento.