2015-09-28 19 views
5

Xin chào các bạn, tôi đang gặp sự cố với NSBatchDeleteRequest dường như không thể xóa các tham chiếu mối quan hệ.NSBatchDeleteRequest không xóa mối quan hệ

Tôi có hai thực thể:

  • Tin tức
  • Categories

nơi một thể loại có thể có nhiều tin tức.

Bây giờ, khi tôi cố xóa tất cả các đối tượng trong dữ liệu lõi bằng cách sử dụng NSBatchDeleteRequest với mã sau, sau đó nhìn vào tệp sqlite dường như tất cả các danh mục đều bị xóa, tất cả tin tức sẽ bị xóa, nhưng mối quan hệ giữa các loại và tin tức vẫn còn, và điều này gây ra lỗi.

Đây là chức năng xóa:

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

Bất kỳ ý tưởng về làm thế nào để sửa lỗi này?

+0

Bạn đang sử dụng quy tắc xóa nào? – Shizam

+0

@Shizam Tôi đang sử dụng Nullify – Serluca

+0

Có bao nhiêu hồ sơ?Ít hơn 10.000? Bạn cũng có thể sử dụng đồ thị đối tượng. – Mundi

Trả lời

4

Đặt shouldDeleteInaccessibleFaults: thành YES và lỗi không thể truy cập/không thể thực hiện được sẽ bị xóa. Điều này giải quyết vấn đề ngay lập tức.

Phiên WWDC 2015 Có gì mới trong Dữ liệu cốt lõi nói về điều này một chút. Cả hai NSBatchDeleteRequestNSBatchUpdateRequest sửa đổi cửa hàng liên tục mà không cần sự tham gia của NSManagedObjectContext - điều này sẽ dẫn đến bối cảnh của dữ liệu không phù hợp với cửa hàng.

Bản sao trong bộ nhớ của đối tượng đã xóa cần được cập nhật trong NSManagedObjectContext - yêu cầu xóa hàng loạt trả lại ID đối tượng của đối tượng đã xóa và thông báo cho NSManagedObjectContext để làm mới các ID đó.

này sẽ giống như thế này:

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

Khi lô xóa chạy, mối quan hệ sẽ bị xóa hoặc vô hiệu hóa, nhưng một bộ tầng quy tắc xóa có thể không được thực thi, và quy tắc xác nhận sẽ không được thực thi - tùy thuộc vào ứng dụng của bạn để đảm bảo tính toàn vẹn dữ liệu khi sử dụng bất kỳ yêu cầu thay đổi hàng loạt nào.

Mô hình dữ liệu của bạn có thể yêu cầu bạn phát hành nhiều yêu cầu xóa để ngăn các đối tượng liên quan bị mồ côi nhưng vẫn có thể tìm thấy. Ví dụ: bạn có thể cần xóa hàng loạt thứ hai để định vị các thực thể có liên quan trước đây hiện có mối quan hệ trống. Các vị cho một yêu cầu như vậy có thể trông giống như:

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

Hoặc có thể sử dụng một subquery vv

+0

Hi @quellish tiếc là không hoạt động, tôi đang làm mới các đối tượng gọi refreshAllObjects trên bối cảnh sau khi xóa lô. Tôi biết đó là đến các ứng dụng, nhưng nếu tôi xóa cả hai thực thể tôi không có bất kỳ tài liệu tham khảo sau đó để loại bỏ các mối quan hệ – Serluca

+0

Nó có vẻ là cần thiết để thiết lập: 'batchDeleteRequest.resultType = NSBatchDeleteResultTypeObjectIDs ' để làm việc này, nếu không result.result mặc định thành trạng thái tức là thành công/thất bại. –

0

Tôi nghĩ rằng giải pháp tốt nhất có thể để đầu xóa các loại trong đồ thị đối tượng, do đó vô hiệu hóa tất cả các mối quan hệ.

Sau đó, bạn có thể tiến hành NSBatchDeleteRequest cho các mục tin tức.

3

Bạn có thể làm [manageObjectContext reset];

Các vấn đề liên quan