2015-09-28 61 views
5

嗨,大家好我有一个问题NSBatchDeleteRequest似乎不可能删除关系引用。NSBatchDeleteRequest不会删除关系

我有两个实体:

  • 新闻
  • 分类

其中一个类别可以有多个消息。

现在,当我尝试删除核心数据中的所有对象,使用NSBatchDeleteRequest与下面的代码,然后调查sqlite文件似乎删除所有类别,所有新闻被删除,但类别和新闻之间的关系持续存在,这会导致错误。

这里删除功能:

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

关于如何解决此问题的任何想法?

+0

你使用的是什么删除规则? – Shizam

+0

@Shizam我正在使用Nullify – Serluca

+0

有多少条记录?少于10,000?你也可以使用对象图。 – Mundi

回答

4

shouldDeleteInaccessibleFaults:设置为YES并且无法访问/无法实现的错误将被删除。这解决了眼前的问题。

WWDC 2015会议Core Data有什么新消息就这一点进行了讨论。 NSBatchDeleteRequestNSBatchUpdateRequest都会修改持久性存储而不需要NSManagedObjectContext的参与 - 这将导致上下文中的数据视图与商店不一致。

已删除对象的内存副本需要在NSManagedObjectContext中更新 - 让批量删除请求返回已删除对象的对象ID,并通知NSManagedObjectContext刷新这些ID。

这将是这个样子:

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

当批量删除运行,关系将被删除或废止,但可能无法执行的级联组的删除规则,验证规则将不会被执行 - 使用任何批量更改请求时,由您的应用程序确保数据完整性。

您的数据模型可能会要求您发出多个删除请求以防止相关对象成为孤儿但仍可找到。例如,您可能需要进行第二批删除才能找到现在有空关系的相关实体。对于这样的请求谓词可能看起来像:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"[email protected] == 0"];

,或者可以使用子查询等

+0

不幸的是@quellish不起作用,我在刷新批处理之后刷新上下文中调用refreshAllObjects的上下文。我知道这取决于应用程序,但如果我删除两个实体,我没有任何参考,然后删除关系 – Serluca

+0

似乎有必要设置: 'batchDeleteRequest.resultType = NSBatchDeleteResultTypeObjectIDs' 为此工作,否则result.result默认为状态,即成功/失败。 –

0

我认为最好的解决办法可能是在对象图首先删除类别,从而抵消所有的关系。

之后,您可以继续为新闻项目NSBatchDeleteRequest

3

你也许可以做[manageObjectContext reset];