核心数据批量更新
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 商店,因此无法更新未保存的项目。
因此要么先保存上下文,要么直接在上下文中更新对象 - 这应该很快,因为它们已经在上下文中注册并且不需要获取。
我正在尝试 运行 对我的核心数据数据库(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 商店,因此无法更新未保存的项目。
因此要么先保存上下文,要么直接在上下文中更新对象 - 这应该很快,因为它们已经在上下文中注册并且不需要获取。