将对象插入核心数据实体时处理重复项

Posted

技术标签:

【中文标题】将对象插入核心数据实体时处理重复项【英文标题】:Handle duplicates when inserting objects to core data entity 【发布时间】:2015-12-16 11:02:58 【问题描述】:

在我的应用程序中,我通过分页从 Web 服务下载数据。输出是一个 json 字典数组。

现在,我将输出 json 数组保存在核心数据中。所以,我的问题是,每次使用结果数组调用 saveInCoreData: 方法时,它都会在数据库中创建重复的对象。如果对象已经存在,我如何检查对象并更新或替换该对象? myId 是唯一键。

// save in coredata
+ (void) saveInCoreData:(NSArray *)arr

// get manageObjectContext
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

NSManagedObjectContext *context = [appDelegate managedObjectContext];

if(arr != nil && arr.count > 0) 

    for(int i=0; i < arr.count; i++)

        SomeEntity *anObj = [NSEntityDescription
                                insertNewObjectForEntityForName:@"SomeEntity"
                                inManagedObjectContext:context];


        anObj.description = [[arr objectAtIndex:i] objectForKey:@"description"];
        anObj.count = [NSNumber numberWithInteger:[[[arr objectAtIndex:i] objectForKey:@"count"] integerValue]];

        // Relationship
        OtherEntity *anOtherObject = [NSEntityDescription
                                   insertNewObjectForEntityForName:@"OtherEntity"
                                   inManagedObjectContext:context];
        creatorDetails.companyName = [[[arrTopics objectAtIndex:i] objectForKey:@"creator"] objectForKey:@"companyName"];
    

【问题讨论】:

假设您正在添加带有属性、名称、id、拍摄日期、位置等的照片。让“id”成为所有照片中唯一的属性,如果是这种情况,只需选择您的照片实体在 xcdatamodeld 和 Inspector 窗口的 Constraints 选项卡中,输入该属性名称,仅此而已,现在当您执行保存时,Core Data 将验证它的唯一性,您将只获得一个实例。 【参考方案1】:

避免重复的最有效方法是获取您已有的所有对象,并在迭代结果时避免处理它们。

从结果中获取 topicIds:

NSArray *topicIds = [results valueForKeyPath:@"topicId"];

使用这些 topicId 获取现有主题:

NSFetchRequest *request = ...;
request.predicate = [NSPredicate predicateWithFormat:@"%K IN %@",
                                 @"topicId", topicIds];
NSArray *existingTopics = [context executeFetchRequest:request error:NULL];

获取已有的 topicIds:

NSArray *existingTopicIds = [existingTopics valueForKeyPath:@"topicId"];

处理结果:

for (NSDictionary *topic in results) 
    if ([existingTopicIds containsObject:topic[@"topicId"]]) 
        // Update the existing topic if you want, or just skip.

        continue;
    

    ...

尝试在处理循环中单独获取每个现有主题,在时间方面效率非常低。权衡是更多的内存使用,但由于您一次只能获取 20 个对象,这应该是完全没有问题的。

【讨论】:

感谢详细解答

以上是关于将对象插入核心数据实体时处理重复项的主要内容,如果未能解决你的问题,请参考以下文章

实体框架在播种数据库上插入重复项[重复]

如何避免插入重复记录?

试图理解核心数据关系或处理重复

在核心数据中查找重复值

删除核心数据中所有未提交的实体[重复]

具有实体框架 6 的 ObjectContext 在现有相关实体上插入重复项