Основные правила удаления данных и отношения "многие ко многим"
Скажите, что у вас есть отделы и сотрудники, и у каждого отдела есть несколько сотрудников, но каждый сотрудник также может быть частью нескольких отделов.
Таким образом, между сотрудниками и отделами существует взаимосвязь "многие-ко-многим". При удалении отдела я хотел бы удалить всех сотрудников, которые являются только частью этого отдела, и аннулировать связь с этим отделом для всех сотрудников, которые также являются членами другого отдела.
Будет ли каскадное правило в обоих направлениях? Или каскадное правило автоматически удаляет всех сотрудников отдела независимо от других веток?
Ответы
Ответ 1
Каскадное правило автоматически удаляет объекты в пункте назначения. Таким образом, если вы удалите отдел, сотрудники будут удалены независимо от количества отделов, в которых они находятся.
Похоже, что поведение, которое вы хотите, немного более тонкое, чтобы удалить только "осиротевших" сотрудников, т.е. тех, у кого нет отдела. Когда вы удалите отдел, хорошим способом найти их было бы сделать что-то вроде этого:
NSManagedObject *doomedDepartment = // get the department to be deleted
NSSet *employees = [doomedDepartment valueForKey:@"employees"];
NSSet *orphanedEmployees = [employees filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"[email protected] == 1"]];
for (NSManagedObject *orphanedEmployee in orphanedEmployees) {
[managedObjectContext deleteObject:orphanedEmployee];
}
[managedObjectContext deleteObject:doomedDepartment];
Ответ 2
Спасибо, алекс. Я, вероятно, сделаю это.
Тем временем я нашел другой способ сделать это:
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];
}
}
}}
Это тоже хорошо работает, но может усложниться, если у вас есть несколько разных сущностей, для которых наблюдается такое поведение.