NSBatchDeleteRequest does not delete relationships

Hi guys, I have a problem with NSBatchDeleteRequest , it seems that it is not possible to delete link links.

I have two objects:

  • news
  • Category

where a category can have some news.

Now, when I try to delete all objects in the main data using NSBatchDeleteRequest with the following code, then looking in the sqlite file it seems that all categories are deleted, all news are deleted, but the relationship between categories and news is saved, and this causes errors.

Here's the delete function:

 NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:entityName]; NSBatchDeleteRequest *delete = [[NSBatchDeleteRequest alloc] initWithFetchRequest:fetchRequest]; [delete setResultType:NSBatchDeleteResultTypeCount]; NSError *error; NSBatchDeleteResult *results = [deleteContext executeRequest:delete error:&error]; 

Any idea on how to fix this?

+5
source share
3 answers

Set shouldDeleteInaccessibleFaults: to YES , and invalid / non-executable errors will be removed. This solves the immediate problem.

WWDC 2015 session What's new in Core Data says a little about this. Both NSBatchDeleteRequest and NSBatchUpdateRequest modify persistent storage without the involvement of NSManagedObjectContext , which will result in the context view of the data being incompatible with the storage.

A copy of the deleted object in memory must be updated in NSManagedObjectContext - if the package deletion request returns the identifiers of the objects of the deleted objects and tells NSManagedObjectContext update these identifiers.

It will look something like this:

 [managedObjectContext performBlock:^{ NSBatchDeleteRequest batchDeleteRequest = [NSBatchDeleteRequest alloc] initWithFetchRequest:fetchRequest]; NSBatchDeleteResult result = nil; result = [managedObjectContext executeRequest:batchDeleteRequest error:&error]; if ([[result result] count] > 0){ [managedObjectContext performBlock:^{ NSArray<NSManagedObjectID *> *objectIDs = (NSArray<NSManagedObjectID *>)[result result]; [objectIDs enumerateObjectsUsingBlock:^(NSManagedObjectID *objID, NSUInteger idx, BOOL *stop) { NSError *error = nil; NSManagedObject *obj = [managedObjectContext existingObjectWithID:objID error:&error]; if (![obj isFault] ) { [managedObjectContext refreshObject:obj mergeChanges:YES]; } }]; }]; } }]; 

When batch deletion starts, the relations will be deleted or canceled, but the cascading set of deletion rules may not be executed, and the verification rules will not be fulfilled - it depends on your application to ensure data integrity when using any of the batch change requests.

In your data model, you may need to issue multiple delete requests to prevent related objects from being lost, but can still be found. For example, you might need a second package deletion to search for previously related objects that now have empty relationships. A predicate for such a query might look like this:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@" toMany.@count == 0"];

Or may use a subquery, etc.

+3
source

Perhaps you can do [manageObjectContext reset];

+3
source

I believe that the best solution might be to first delete the categories in the object graph, thereby canceling all relationships.

After that, you can go to NSBatchDeleteRequest for news.

0
source

Source: https://habr.com/ru/post/1232475/


All Articles