问题描述
|
假设我有一个自定义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上文所述,此链接可能也对专业人士有所帮助:
在核心数据中立即传播删除