CoreData关系一遍又一遍地保存了两个

Posted

技术标签:

【中文标题】CoreData关系一遍又一遍地保存了两个【英文标题】:CoreData relation saved two over and over again 【发布时间】:2021-06-01 19:11:13 【问题描述】:

我有一个“列表”实体,它与带有“标签”的 manny 有关系。我将数据从 json 中保存为一个,如下所示:

         func saveData(contex: NSManagedObjectContext) 
            
            listings.forEach()  (data) in
                   
            let listingFetch: NSFetchRequest<Listing> = Listing.fetchRequest()
              listingFetch.predicate = NSPredicate(format: "id = %@",  "\(Int64(data.id))")
                   
                do 
                 let results:[Listing] = try contex.fetch(listingFetch)
                    if results.count == 0 

                       let entity = Listing(context: contex)
                        
                        entity.id = Int64(data.id)
                        entity.title = data.title
                        entity.name = data.name
                        data.tags.forEach  (tagData) in
                            let tag = Tag(context: contex)
                            tag.tagName = (tagData)
                            tag.toListing = entity
                            
                        
                        data.images.forEach  (galleryData) in
                            let image = Gallery(context: contex)
                            image.imageName = galleryData
                            image.galtolisting = entity
                        
                        
                        try? contex.save()
                        print ("Insert Listing: ID: \(entity.id); Title: \(String(describing: entity.title)); Tags: \(String(describing: data.tags)); Images: \(String(describing: data.images))")
                    
                    else
                    
                       let entity = results[0]
                        entity.id = Int64(data.id)
                        entity.title = data.title
                        entity.name = data.name
                        data.tags.forEach  tagData in
                            let tag = Tag(context: contex)
                            tag.tagName = tagData
                            tag.toListing = entity
                        
                        data.images.forEach  galleryData in
                            let image = Gallery(context: contex)
                            image.imageName = galleryData
                            image.galtolisting = entity
                        
                        try? contex.save()
                        print ("Updated Listing: ID: \(entity.id); Title: \(String(describing: entity.title)); Tags: \(String(describing: data.tags)); Images: \(String(describing: data.images))")
                        
                    
                    
                 catch let error as NSError 
                    print("error inserting / updating Listing \(error), \(error.userInfo)")
                
            
      
        

我遇到的问题是,当我再次获取更新数据时,所有“标签”都是重复的。

“列表”实体约束设置为 id。

【问题讨论】:

如果列表已经存在,您可以从 json 中添加所有标签,而不检查它们是否已经存在于该列表对象中。 【参考方案1】:

每次这条线运行时:

let tag = Tag(context: contex)

你告诉 Core Data 创建一个新的Tag。如果您不想创建新的Tag,则需要找到已经存在的实例并更新它们。你可以这样做

使用基于tagName 的谓词获取Tag。检查是否已经存在具有该名称的Tag。如果是这样,请更新它。如果没有,请创建一个新的。这更容易,但可能更慢。 获取所有Tag 实例并将它们保存在字典中,其中键为tagName。然后您可以在字典中查找必要的Tag 是否存在,然后创建一个或更新您已有的。这并不难,但也没有那么容易,但可能会更快。

【讨论】:

这个答案假设一个多对多的关系,我觉得它是一个一对多的关系 OP 正在使用虽然它很可能是一个多对多的更好的关系跨度> 【参考方案2】:

最终.. 工作代码。新标签会保存在旧标签之上。

           data.tags.forEach  (tagData) in
                            let tagFetch: NSFetchRequest<Tag> = Tag.fetchRequest()
                            tagFetch.predicate = NSPredicate(format: "tagName = %@",  tagData)
                            
                            do 
                                let tagresults:[Tag] = try contex.fetch(tagFetch)
                                if tagresults.count == 0 
                                    if tagData.count > 0 
                                        let tag = Tag(context: contex)
                                        tag.tagName = (tagData)
                                        tag.toListing = entity
                                    
                                
                            
                            catch let error as NSError 
                                print("error inserting / updating Listing \(error), \(error.userInfo)")
                            
                            
                        

现在。如果它们在传入的更新中不存在,则必须找到一种方法从 CD 中删除这些标签。 EX 用户编辑了列表并删除了一些标签!

【讨论】:

"tagName = %@", tagData,这真的有效吗? tagData 不是 Tag 对象吗? 是的!我没有错误。来自 json 的新标签保存在 CD 中。这种方式我只添加不是一个完整的更新,如果标签从 json 中删除它们仍然在 CD 中,你知道我怎样才能只删除不包含的标签吗? 一种方法是删除所有标签,然后添加新标签。另一种方法是使用两个 Set 对象而不是数组来比较差异。

以上是关于CoreData关系一遍又一遍地保存了两个的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Run 一遍又一遍地错误运行

为啥 OnPreRender 被一遍又一遍地调用?

为啥这不会一遍又一遍地返回一个新值?爪哇

Listview一遍又一遍地只显示最后一项

为啥在反应的“useState”钩子中一遍又一遍地设置初始状态

如何阻止innerHtml表一遍又一遍地重复自己?