核心数据批量更新

Core Data batch update

我正在尝试 运行 对我的核心数据数据库(SQLite)中的选定对象进行批量更新,但我的请求 returns 更新了 0 个项目(没有错误消息)。我的实体 "SDRDFileObject" 有一个 属性 selected(在我的模型中为 Bool),我想为满足我的获取谓词的所有对象将其设置为 NO

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(isLeaf == 1) AND (direction ==  1) AND (myLR == 1)"];

 NSEntityDescription *entity = [NSEntityDescription entityForName:@"SDRDFileObject"
                                     inManagedObjectContext:self.context];

NSBatchUpdateRequest *reqL = [[NSBatchUpdateRequest alloc] initWithEntity:entity];
reqL.predicate = predicate;
reqL.resultType = NSUpdatedObjectIDsResultType;

reqL.includesSubentities = YES;
reqL.propertiesToUpdate = @{
                            @"selected" : @(NO)
                            };

NSError *error;
NSBatchUpdateResult *resL = (NSBatchUpdateResult *)[self.context executeRequest:reqL error:&error];

这 returns 0 项已更新。但是,如果我使用相同的设置来估计受影响对象的数量,我会得到 1764(这是正确的):

 NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
[request setResultType:NSUpdatedObjectIDsResultType];
[request setReturnsDistinctResults:YES];
[request setPropertiesToFetch:@[@"selected"]];


NSError *err;
NSUInteger count = [self.context countForFetchRequest:request error:&err];

NSLog(@"Estimated fetch request count : %li",count);

有人对我在这里做错了什么有建议吗?我应该写 keyPath 有什么不同吗?我感谢建议和帮助。

更新 我遵循了调试 SQL 命令的建议,但它似乎失败了,尽管我不确定如何解释错误消息。第一个 SQL 调用是针对成功的 countForFetchRequest,然后是失败的批处理请求。

CoreData: sql: SELECT COUNT( DISTINCT t0.Z_PK) FROM ZSDRDFILEOBJECT t0     WHERE ( t0.ZISLEAF = ? AND  t0.ZDIRECTION = ? AND  t0.ZMYLR = ?) 
CoreData: annotation: total count request execution time: 0.0005s for count of 0.
2017-11-15 16:56:09.560121+0100 TEST[69278:3739361] Estimated fetch  request count : 1764
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: SELECT 0, t0.Z_PK FROM ZSDRDFILEOBJECT t0 WHERE (  t0.ZISLEAF = ? AND  t0.ZDIRECTION = ? AND  t0.ZMYLR = ?) 
CoreData: annotation: sql connection fetch time: 0.0000s
CoreData: annotation: total fetch execution time: 0.0001s for 0 rows.
CoreData: sql: UPDATE OR FAIL ZSDRDFILEOBJECT SET ZSELECTED = ?, Z_OPT = (Z_OPT + 1) WHERE (ZISLEAF = ? AND ZDIRECTION = ? AND ZMYLR = ?) 
CoreData: sql: pragma auto_vacuum
CoreData: annotation: sql execution time: 0.0000s
CoreData: sql: pragma auto_vacuum=2
CoreData: annotation: sql execution time: 0.0003s
CoreData: sql: COMMIT

第一个SQL计数returns 0,但上下文returns 1764。所以看起来符合您条件的对象尚未保存到SQL网站商店。批量更新直接作用于 SQLite 商店,因此无法更新未保存的项目。

因此要么先保存上下文,要么直接在上下文中更新对象 - 这应该很快,因为它们已经在上下文中注册并且不需要获取。