【发布时间】:2011-01-25 12:31:32
【问题描述】:
我目前正在将使用 SQLite 的 iphone 应用程序迁移到 CoreData。
我需要执行 INSERT 或 REPLACE 以仅添加新内容,有没有办法做到这一点,还是我必须获取所有数据库并查找现有对象并添加新内容?
谢谢。
【问题讨论】:
标签: iphone cocoa cocoa-touch sqlite core-data
我目前正在将使用 SQLite 的 iphone 应用程序迁移到 CoreData。
我需要执行 INSERT 或 REPLACE 以仅添加新内容,有没有办法做到这一点,还是我必须获取所有数据库并查找现有对象并添加新内容?
谢谢。
【问题讨论】:
标签: iphone cocoa cocoa-touch sqlite core-data
请记住,Core Data 是一个对象层次结构,碰巧会持久化到数据库中,因此您需要将其视为对象图,而不是数据库。
因此,是的,您需要使用某个定义的唯一 ID 检查对象是否已存在,如果当前不存在,则需要创建新对象与更新现有对象。
您不需要获取所有对象,使用NSFetchRequest 和NSPredicate 搜索商店以检查是否存在;如果存在则更新,如果不创建。
【讨论】:
参见Apple document,标题为“高效导入数据”。这正是您想学习的主题。尤其要仔细阅读“高效实现查找或创建”部分。
当然,购买 Marcus Zarra 的 Core Data 书籍非常棒:)
【讨论】:
基本上,我们对插入(获取)数据和 json 数据进行排序,因此在每个索引处,它们具有相同的值。然后我们检索相应索引处的值并更新托管对象,如果计数器大于获取的结果长度,我们插入一个新的托管对象。
//Add JSON objects into entity
- (void) insertUpdate:(NSArray *)jsonArrayData {
//sort JSON Data
NSSortDescriptor *idDescriptor = [[NSSortDescriptor alloc] initWithKey:@"entityID" ascending:YES selector:@selector(localizedStandardCompare:)];
NSArray *sortDescriptors = @[idDescriptor];
NSArray *sortedJSONArray = [jsonArrayData sortedArrayUsingDescriptors:sortDescriptors];
//get entity
NSEntityDescription *entity = [NSEntityDescription entityForName:@"entity" inManagedObjectContext:self.managedObjectContext];
// Get the ids from json in sorted order.
NSMutableArray *entityIDs = [[NSMutableArray alloc]init];
for (NSDictionary *jsonValues in jsonArrayData) {
id value = [jsonValues objectForKey:@"entityID"];
[entityIDs addObject:value];
}
//sort to make sure json and fetched data are both sorted in same manner
[entityIDs sortUsingSelector:@selector(compare:)];
// create the fetch request to get all Entities matching the IDs
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
NSString *filter = @"(%K IN %@)";
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: filter, @"entityID", entityIDs]];
// Make sure the results are sorted as well.
[fetchRequest setSortDescriptors:
@[ [[NSSortDescriptor alloc] initWithKey: idName ascending:YES] ]];
// Execute the fetch.
NSError *fetchError;
NSArray *entityMatchingNames = [self.elRehabCoreData.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
int i = 0;
//loop over JSONData
for (NSDictionary *keyedValues in sortedJSONArray) {
id value = [keyedValues objectForKey:@"entityID";
//Create NSManagedObject
NSManagedObject *managedObject = nil;
int updateInsert = 0;
if(entityMatchingNames.count > i ){
//update
managedObject = [entityMatchingNames objectAtIndex:i];
if ([[managedObject valueForKey:@"entityID"] isEqual:[keyedValues valueForKey:@"entityID"]]){
updateInsert = 1;
}
}else{
//insert
managedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
updateInsert = 1;
}
i++;
//set value if updateInsert is true
// The updateInsert flag is an extra security to make sure we only update when the value in JSON data is equal that of fetched data
if (updateInsert) {
[managedObject setValue:value forKey:attribute];
}
}
//save core data stack
[self saveContext];
}
【讨论】: