Основные правила удаления данных и отношения «многие ко многим»
-
06-07-2019 - |
Вопрос
Допустим, у вас есть отделы и сотрудники, и в каждом отделе есть несколько сотрудников, но каждый сотрудник также может входить в несколько отделов.
Таким образом, между сотрудниками и отделами существует много-много связей. При удалении отдела я хотел бы удалить всех сотрудников, которые являются только частью этого отдела, и аннулировать связь с этим отделом для всех сотрудников, которые также являются членами другого отдела.
Будет ли каскадное правило в обоих направлениях делать это? Или каскадное правило автоматически удаляет всех сотрудников отдела независимо от других связей?
Решение
Каскадное правило автоматически удалит объекты в месте назначения. Таким образом, если вы удалите отдел, сотрудники будут удалены независимо от количества отделов, в которых они находятся.
Похоже, что поведение, которое вы хотите, немного более нюансировано, чтобы удалить только "потерянные" " сотрудники - то есть те, у кого нет отдела. Когда вы удаляете отдел, хорошим способом его поиска было бы сделать что-то вроде этого:
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];
Другие советы
Спасибо, Алекс. Я, вероятно, сделаю это. Тем временем я нашел другой способ сделать это:
1.) зарегистрируйтесь для получения уведомлений об изменениях:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(managedObjectContextDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:managedObjectContext];
2.) когда происходят изменения и сотрудник обновляется. Я проверяю, имеет ли этот объект 0 отношений с отделами, и удаляю его:
- (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];
}
}
}}
Это тоже хорошо работает, но может стать более сложным, если у вас есть несколько разных сущностей, для которых можно наблюдать такое поведение.