【问题标题】:CoreData relation saved two over and over againCoreData关系一遍又一遍地保存了两个
【发布时间】: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 中添加所有标签,而不检查它们是否已经存在于该列表对象中。

标签: json swift core-data entity-relationship


【解决方案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 对象而不是数组来比较差异。
猜你喜欢
  • 2014-05-11
  • 2014-02-16
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多