sti*_*fin 20 macos cocoa core-data objective-c
假设我有一个自定义的NSManagedObject Department,它有一个表示与员工的多对多关系的属性,即NSSet *employees;.
对于给定的部门,我想删除员工中的所有对象.请问有什么建议/最好的方法吗?
所以,假设我的代码看起来像这样:
Department.h
@interface Department: NSManagedObject {
}
@property (retain) NSString *departmentName;
@property (retain) NSSet *employees;
@end
Run Code Online (Sandbox Code Playgroud)
Department.m
@implementation Department
@dynamic departmentName;
@dynamic employees;
Run Code Online (Sandbox Code Playgroud)
Employee.h
@interface Employee: NSManagedObject {
}
@property (retain) NSString *firstName;
@property (retain) NSString *lastName;
@property (retain) Department *worksIn;
@end
Run Code Online (Sandbox Code Playgroud)
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."
Run Code Online (Sandbox Code Playgroud)
这种关系employees不是可选的,因此我猜测从部门中删除员工意味着我正在尝试"孤儿"员工,即将员工留在持久模型中而没有相关部门.
因此,我认为我的原始问题应该改为:当孩子与父母有非可选关系时,什么是最好/推荐的方法来删除"父母"的所有"子"对象?
我怀疑答案是"循环并一次删除一个员工对象".
UPDATE
根据答案和Apple文档的链接,我应该能够将删除规则设置为"Cascade",然后代码department.employees = [NSSet set];就可以了.但是,这在我已经相应设置删除规则的非常简单的项目中不起作用.
谢谢
Sco*_*eil 18
将部门的员工关系设置为空集不会删除员工,无论删除规则如何.我相信你误解了删除规则.根据苹果文档:"关系的删除规则指定了在尝试删除源对象时应该发生什么".因此,级联只有在我们删除部门时才会生效.通过将关系设置为空集,我们所做的只是将员工与部门分开,而不是删除它们.如果员工的关系未设置为可选,则在保存时会导致错误.如果要从部门中删除员工,可以按上面列出的方式对其进行迭代,或者将部门关系设置为级联,然后删除部门.
Rem*_*hem 16
如果要删除特定部门的员工元素,则可以像for一样运行for-in循环
for (Employees * theEmployee in department.employees) {
[self.managedObjectContext deleteObject:[self.managedObjectContext objectWithID:theEmployee.objectID]];
}
Run Code Online (Sandbox Code Playgroud)
然后保存您的托管上下文.如果这是你想要的,而不是消除员工和部门之间的关系; 在这种情况下,分配一个空集将起作用.
以上变化:
for (Employee *employeeToDelete in department.employees) {
[self.managedObjectContext deleteObject:employeeToDelete];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24716 次 |
| 最近记录: |