如何通过核心数据关系删除所有对象?
假设我有一个自定义的NSManagedObject Department
,并且这个属性表示与员工的多对多关系,即NSSet *employees;
。如何通过核心数据关系删除所有对象?
对于给定的部门,我想删除全部员工中的对象。请推荐/最好的方法是什么?
所以,假设,我的代码是这样的:
Department.h
@interface Department: NSManagedObject {
}
@property (retain) NSString *departmentName;
@property (retain) NSSet *employees;
@end
Department.m
@implementation Department
@dynamic departmentName;
@dynamic employees;
Employee.h
@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."
的关系employees
是不可选的,所以我猜测,从部门员工删除意味着,我想“孤儿”的员工,即员工保持在坚持没有相关部门的模型。
因此,我认为我的原始问题应该重写为:当孩子与父母有非选择性关系时,什么是最好的/推荐的方式来删除“父母”的所有“孩子”对象?
我怀疑答案是“循环并逐个删除一个员工对象”。
UPDATE
根据答案,苹果的文档的链接,我应该能够设置删除规则“瀑布”,然后像department.employees = [NSSet set];
代码将工作。但是,这在我非常简单的项目中无效,因为我已经相应地设置了删除规则。
感谢
如果你想删除员工元素特定部门,那么你就可以运行了,在像
for (Employees * theEmployee in department.employees) {
[self.managedObjectContext deleteObject:[self.managedObjectContext objectWithID:theEmployee.objectID]];
}
然后保存管理的背景下循环。如果当然这就是你想要的,而不是消除员工和部门之间的关系;在这种情况下,分配一个空集将起作用。
变化上面:
for (Employee *employeeToDelete in department.employees) {
[self.managedObjectContext deleteObject:employeeToDelete];
}
只是将循环的指针'theEmployee'设置为零,它根本不会影响管理对象。 – 2011-06-11 21:56:36
我的不好,编辑;) – 2011-06-12 00:31:17
目前,这是我使用的技术,因为我不能让级联删除工作...除了我的更简单。我已将它粘贴到您的代码下面 – stifin 2011-06-13 14:49:23
设置为空集该部门的雇员的关系将不会删除员工,无论是删除规则的。我相信你误解了删除规则。根据苹果文档: “关系的删除规则指定如果尝试删除源对象应该发生的情况”。 因此,级联只会在我们删除部门时生效。通过将关系设置为空集,我们所做的就是将员工与部门分离,而不是将其删除。如果员工没有将这种关系设置为可选,这将在保存时导致错误。如果您想从部门中删除员工,则可以按照上面列出的方法遍历他们,或者将部门关系设置为级联,然后删除部门。
谢谢 - 你的答案到了问题的根源,并确认我是如何怀疑删除规则的工作。我想如果你添加了一些代码,它会成为(当然应该)首选的答案。 – Benjohn 2017-05-12 11:37:00
我也有过类似下面,但它没有工作...
- (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;
}
显然,数据库层无法删除的声音,然后收集一次。 设置删除规则的关系,以“级联”很好地解决我的问题,让我只需使用:
[context deleteObject:collection];
如果你想节省一些人详细阅读时间则只是标记这个作为答案。
由于Fervus如上所述,这个环节也可能是有用的优点: Propagate deletes immediately in Core Data
我不知道,如果你已经找到了解决这一问题?我有同样的问题..坚持你的例子我有一个同步过程中,我试图删除所有员工,然后从头开始创建它们(不要让我的同步过于复杂)..但目前唯一的方法我得到这个工作就是去掉双方的'to many'关系 - 迭代员工调用[managedObjectContext deleteObject:employee],然后执行[[department mutableSetValueForKey:@“employees”] removeAllObjects];这似乎是错误的,但工程.. – herbert 2011-11-05 11:32:09
我从来没有得到上面的例子工作。最后,我重复了员工并删除了他们,如下面我刚刚接受的答复 – stifin 2011-11-13 13:58:00
您误解了文档。删除部门对象时,删除规则将应用于员工集中的员工对象。改变关系不会删除任何对象。 – Eric 2012-05-09 20:21:04