iPhone核心数据:跨多对一关系的级联删除

时间:2010-02-04 23:59:53

标签: iphone cocoa cocoa-touch core-data cascading-deletes

我有两个A和B类,从A到B有多对一的关系(多个A对象可能引用相同的B)。问题是,如果A侧的删除规则是Cascade,则只有在最后引用A被删除时才删除B,或者删除第一次时间关联的A被删除。如果重要的话,关系B侧的删除规则是Nullify。

另外,我在Core Data文档中读到,Optional标志在某些情况下很重要。但目前尚不清楚他们所说的关系与我的案例有何关系。他们在讨论收容案(B由A拥有),而我的案例是订阅/关联(B与A有关)。

我可以简单地在代码中管理删除programmaticaly,但是如果可能的话,希望允许Core Data做正确的事情。但目前尚不清楚核心数据是否支持我正在寻找的垃圾收集语义。

有什么建议吗?

3 个答案:

答案 0 :(得分:15)

我的目标与您显然相同(删除 B 后,删除最后一次引用的 A )。为了做到这一点,我花了比预期更长的时间。特别是因为

  • A 准备删除时, B 中的多对多关系可能尚未更新,因此您无法计算 A B
  • 中引用
  • isDeleted on A 似乎已在-prepareForDeletion期间设置

如果有人感兴趣的话,这对我有用(我将使用部门< - >> 员工,因为它更容易阅读):

员工

- (void)prepareForDeletion {
    // Delete our department if we we're the last employee associated with it.
    Department *department = self.department;
    if (department && (department.isDeleted == NO)) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isDeleted == NO"];
        NSSet *employees = [department.employees filteredSetUsingPredicate:predicate];

        if ([employees count] == 0) {           
            [self.managedObjectContext deleteObject:department];
        } 
    }
}

其他人建议将此逻辑放入部门中的-willSave。我更喜欢上面的解决方案,因为在某些情况下我可能真的想要保存一个空的部门(例如在手动存储迁移或数据导入期间)。

答案 1 :(得分:0)

这是Lukas答案的 Swift 4 版本:

public override func prepareForDeletion() {
    guard let department = department else { return }

    if department.employees.filter({ !$0.isDeleted }).isEmpty {
        managedObjectContext?.delete(department)
    }
}

答案 2 :(得分:0)

添加到@JanApotheker 答案中,您还需要保存 managedObjectContext 并将过滤器的参数转换为 AnyObject,因为它像这样迭代 NSSet:-

public override func prepareForDeletion() {
    guard let department = department, let employees = department.employees else { return }

    if employees.filter({ !($0 as AnyObject).isDeleted }).isEmpty {
        managedObjectContext?.delete(department)
        do {
            try managedObjectContext?.save()
        } catch {
            
        }
    }
}