核心数据删除规则和多对多关系

Fel*_*oux 11 cocoa database-design core-data objective-c relationships

假设您有部门和员工,每个部门都有几名员工,但每个员工也可以成为多个部门的一部分.

因此,员工和部门之间存在多对多的关系.删除部门时,我希望删除仅属于该部门的所有员工,并取消与该部门的关系,以便同时也是其他部门成员的所有员工.

两个方向的级联规则是否会这样做?或者,级联规则是否自动删除部门的所有员工,而不管其他任何从属关系?

Ale*_*lex 21

级联规则将自动删除目标上的对象.因此,如果删除某个部门,员工将被删除,无论他们所在的部门数量如何.

听起来你想要的行为有点微妙,只删除"孤儿"员工 - 即那些没有部门的员工.删除部门时,找到这些部门的好方法是执行以下操作:

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];
Run Code Online (Sandbox Code Playgroud)


Fel*_*oux 5

谢谢,亚历克斯.我可能会这样做.与此同时,我发现了一种不同的方式:

1.)注册变更通知:

    [[NSNotificationCenter defaultCenter] addObserver:self 
            selector:@selector(managedObjectContextDidChange:) 
            name:NSManagedObjectContextObjectsDidChangeNotification 
            object:managedObjectContext];
Run Code Online (Sandbox Code Playgroud)

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];
        }
    }
}}
Run Code Online (Sandbox Code Playgroud)

这也很有效,但是如果你有几个不同的实体来观察这种行为,可能会变得更复杂.

  • 如果你正在使用Cocoa Touch或Snow Leopard,你可以将这个逻辑放在部门的`-prepareForDeletion`方法中. (4认同)