3

My CoreData model got two child entities "CarA" and "CarB" with the same abstract parent entity "Car".

I'm trying to delete all CarA objects using

    func deleteObjects(entityName: String) {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        do {
            try context.execute(deleteRequest)
        } catch let error as NSError {
            print(error)
        }
    }

Executing deleteObjects("CarA") results in deleting not only all CarA objects, but also all CarB objects as well.

Paul
  • 272
  • 1
  • 6

1 Answers1

3

This looks to me like a bug. If you enable SQLDebug, you can see from the console output that the entire parent entity is deleted:

CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: DELETE FROM ZABSTRACT
CoreData: sql: COMMIT

(my parent entity is named "Abstract"). But I notice that if you add a predicate, CoreData remembers to qualify the underlying fetch to restrict it to the correct child entity. So a workaround is to add a predicate that is always true:

fetchRequest.predicate = NSPredicate(value:true)

and the resulting console output is:

CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: DELETE FROM ZABSTRACT WHERE Z_PK IN (SELECT t0.Z_PK FROM ZABSTRACT t0 WHERE  t0.Z_ENT = ? )
CoreData: sql: COMMIT

It seems CoreData even optimises out the true predicate, leaving only the WHERE clause to limit the delete to the correct entity.

pbasdf
  • 21,386
  • 4
  • 43
  • 75