如何通过核心数据关系删除所有对象?

问题描述

| 假设我有一个自定义NSManagedobject
Department
,并且它具有一个表示与员工的一对多关系的属性,即
NSSet *employees;
。 对于给定的部门,我想删除员工中的所有对象。请执行此操作的推荐/最佳方法是什么? 因此,假设我的代码如下所示: 部门
@interface Department: NSManagedobject {
}
@property (retain) Nsstring *departmentName;
@property (retain) NSSet *employees;
@end
部门
@implementation Department
@dynamic departmentName;
@dynamic employees;
员工
@interface Employee: NSManagedobject {
}
@property (retain) Nsstring *firstName;
@property (retain) Nsstring *lastName;
@property (retain) Department *worksIn;
@end
doCoreDataStuff
- (void)doCoreDataStuff:sender {
    //add a department,give it a couple employees,then try to remove those employees
    NSEntityDescription *deptEntity = [NSEntityDescription entityForName:@\"Department\"
                                                 inManagedobjectContext:self.managedobjectContext];
    Department *dept = [Department alloc] initWithEntity:deptEntity
                          insertIntoManagedobjectContext:self.managedobjectContext];
    NSError *error;

    dept.departmentName = @\"Accounting\";
    //save more often than normal to see more easily what causes error
    if (![self.managedobjectContext save:&error]) NSLog(@\"\\nError: %@\",[error localizedDescription]);

    NSEntityDescription *empEntity = [NSEntityDescription entityForName:@\"Employee\"
                                                 inManagedobjectContext:self.managedobjectContext];
    emp.firstName = @\"Steve\";
    emp.lastName = @\"Smith\";
    emp.worksIn = dept;

    if (![self.managedobjectContext save:&error]) NSLog(@\"\\nError: %@\",[error localizedDescription]);

    emp = [[Employee alloc] initWithEntity:empEntity
            insertIntoManagedobjectContext:self.managedobjectContext];
    emp.firstName = @\"Natasha\";
    emp.lastName = @\"Johnson\";
    emp.worksIn = dept;

    if (![self.managedobjectContext save:&error]) NSLog(@\"\\nError: %@\",[error localizedDescription]);

    //all good so far! Now will try to delete all employees for this department
    dept.employees = [NSSet set];
    if (![self.managedobjectContext save:&error]) NSLog(@\"\\nError: %@\",[error localizedDescription]); //\"Multiple validation errors occurred.\"

    //this also produces the same error
    [[dept mutableSetValueForKey:@\"employees\"] removeAllObjects];
    if (![self.managedobjectContext save:&error]) NSLog(@\"\\nError: %@\",[error localizedDescription]); //\"Multiple validation errors occurred.\"
关系“ 6”不是可选的,因此我猜想从部门中撤离员工意味着我试图“孤立”员工,即,使员工处于没有关联部门的持久化模型中。 因此,我认为我的原始问题应该改写为:当孩子与父母之间存在非可选关系时,删除“父母”中所有“孩子”对象的最佳/推荐方法是什么? 我怀疑答案将是“遍历并一次删除一个雇员对象”。 更新 根据一个答案和指向Apple文档的链接,我应该能够将删除规则设置为“ Cascade”,然后像“ 7”这样的代码将起作用。但是,这在我非常简单的项目中不起作用,在该项目中我相应地设置了删除规则。 谢谢     

解决方法

        如果要删除特定部门的员工元素,则可以运行for循环
for (Employees * theEmployee in department.employees) {
  [self.managedObjectContext deleteObject:[self.managedObjectContext objectWithID:theEmployee.objectID]]; 
}
然后保存您的托管上下文。当然,这就是您想要的,并且不能消除员工与部门之间的关系;在这种情况下,可以分配一个空集。 上面的变化:
for (Employee *employeeToDelete in department.employees) {
    [self.managedObjectContext deleteObject:employeeToDelete];
}
    ,        将部门的员工关系设置为空集,无论删除规则如何,都不会删除员工。我相信您误解了删除规则。根据苹果文档: \“关系的删除规则指定了尝试删除源对象时应该怎么办\”。 因此,只有我们删除部门后,级联才会生效。通过将关系设置为空集,我们要做的就是将员工与部门分开,而不是删除员工。而且,如果该关系对于员工没有设置为可选,则在保存时将导致错误。如果要从部门中删除员工,则可以按上面列出的步骤对其进行遍历,或者将部门关系设置为级联,然后删除该部门。     ,        我也有类似下面的内容,但是没有用...
- (BOOL)deleteCollection:(Collection *)collection {
    // Grab the context
    NSManagedObjectContext *context = [self managedObjectContext];
    NSError *error = nil;

    [collection removeSounds:collection.sounds];
    [context deleteObject:collection];

    // Save everything
    if ([context save:&error]) {
        return YES;
    }
    return NO;
}
显然,数据库层无法一次删除声音,然后立即删除集合。将关系的删除规则设置为\'cascade \'很好地解决了我的问题,让我只使用:
[context deleteObject:collection];
如果您想节省一些人的详细阅读时间,只需将其标记为答案即可。 正如Fervus上文所述,此链接可能也对专业人士有所帮助: 在核心数据中立即传播删除