iPhone Core Data: Cascading delete across a many-to-one relationship

前端 未结 2 1182
遥遥无期
遥遥无期 2020-12-24 13:20

I have two classes A and B with a many-to-one relationship from A to B (multiple A objects may reference the same B). The question is, if the delete rule on the A side is C

相关标签:
2条回答
  • 2020-12-24 14:02

    Here's a Swift 4 version of Lukas' answer:

    public override func prepareForDeletion() {
        guard let department = department else { return }
    
        if department.employees.filter({ !$0.isDeleted }).isEmpty {
            managedObjectContext?.delete(department)
        }
    }
    
    0 讨论(0)
  • 2020-12-24 14:22

    I had the same goal as you apparently had (delete B as soon as the last referenced A is deleted). It took me longer than expected to get this right. Particularly because

    • At the time A prepares for deletion, the to-many relationship in B might not be updated yet, so you can't just count the A referenced in B.
    • isDeleted on A seems to be already set during -prepareForDeletion

    Here's what worked for me if anybody's interested (I'll use Department <-->> Employee because it's easier to read):

    In Employee:

    - (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];
            } 
        }
    }
    

    Other people have suggested putting this logic into -willSave in Department. I prefer the solution above since I might actually want to save an empty department in some cases (e.g. during manual store migration or data import).

    0 讨论(0)
提交回复
热议问题