swiftcore-data

How to efficiently delete CoreData relationship child objects


I have one-to-many relationship in CoreData defined in the following way:

private func configureOneToManyRelationship(sourceEntity: NSEntityDescription,
                                            sourcePropertyName: String,
                                            destinationEntity: NSEntityDescription,
                                            destinationPropertyName: String,
                                            isOrdered: Bool = true) {
        let relationship = NSRelationshipDescription()
        relationship.name = sourcePropertyName
        relationship.destinationEntity = destinationEntity
        relationship.minCount = 0
        relationship.maxCount = 0
        relationship.deleteRule = .cascadeDeleteRule
        relationship.isOrdered = isOrdered
        
        let inverseRelationship = NSRelationshipDescription()
        inverseRelationship.name = destinationPropertyName
        inverseRelationship.destinationEntity = sourceEntity
        inverseRelationship.minCount = 0
        inverseRelationship.maxCount = 1
        inverseRelationship.deleteRule = .nullifyDeleteRule
        
        relationship.inverseRelationship = inverseRelationship
        inverseRelationship.inverseRelationship = relationship
        
        sourceEntity.properties.append(relationship)
        destinationEntity.properties.append(inverseRelationship)
    }

Then I create two entities and set the one-to-many relationship:

let parentEntity = buildParentEntity()
let childEntity = buildChildEntity()

configureOneToManyRelationship(sourceEntity: parentEntity,
                               sourcePropertyName: "children",
                               destinationEntity: childEntity,
                               destinationPropertyName: "parent")

So my parent managed object has NSOrderedSet* children which contains the children in the relationship.

What is the best (most efficient) way to delete all children (and removing from the persistent store) without deleting the parent?

I tried to set parent.children = NSOrderedSet() which removes the children objects from the relationship but does not delete them from the persistent store even though the delete rule is .cascadeDeleteRule.

Should I iterate each child and call context.delete(child) or use NSBatchRequest or any other solution exists?

Also if .cascadeDeleteRule applies only to deleting the whole parent object then what about the following solution:

  1. To have intermediate List entity with one-to-many relationship to my children and cascade delta rule
  2. To set one-to-one relationship between parent and List
  3. When need to reset the children will just delete the list from the parent which will delete all child elements

Solution

  • The delete rule only applies when deleting the parent object, not when removing objects from its relationship. I don’t think there’s a performance advantage to deleting via a delete rule. So I would just iterate and use context.delete(child). Batch deleting is not intended for objects that are in relationships.