用Core Data插入/更新记录的最有效方法? [英] Most efficient way to insert/update records with Core Data?

查看:91
本文介绍了用Core Data插入/更新记录的最有效方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个可定期从服务器下载数据的应用程序.如果需要更新数据,我将使用类似以下的方法来更新记录或插入不存在的新记录.

I am developing an app that downloads data from a server regularly. If the data needs updated, I use something like to following to update the records or insert new records if they don't exist.

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Trip")
    for csvTrip in csvTrips {
        var trip: NSManagedObject!

        let tripId = Int(csvTrip[0])!
        fetchRequest.predicate = NSPredicate(format: "id = %d", tripId)

        if (context.count(for: fetch) == 0) {
            trip = NSEntityDescription.insertNewObject(forEntityName: "Trip", into: context)
            trip.setValue(tripId, forKey: "id")
        } else {
            tripObject = (context.fetch(fetch) as! [NSManagedObject])[0]
        }

        // Set other properties
    }

检查该实体是否已存在于每个循环中,这使其比不检查就插入它们慢了大约100倍,这对于成千上万个实体来说是一个大问题.我尝试过先获取所有实体,但仍然必须遍历每个实体,并将id添加到数组或其他内容中,这并不快.我知道核心数据与MySQL不同,但是我很难相信没有类似于INSERT ... ON DUPLICATE KEY UPDATE的功能,这在MYSQL中非常快.我想念什么吗?

Checking if the entity already exists in each loop makes it about 100 times slower than just inserting them without checking, which becomes a big problem with more than a few thousand entities. I've tried fetching all the entities first, but I still have to loop through each one and add the id to an array or something, which isn't much faster. I know core data isn't the same as MySQL, but it's hard for me to believe that there isn't a feature similar to INSERT ... ON DUPLICATE KEY UPDATE, which is extremely fast in MYSQL. Am I missing something?

推荐答案

如果获取甚至数千个实体并将id加载到 Set 中的时间特别长,我会感到惊讶.

I would be surprised if fetching even a few thousand entities and loading the ids into a Set took a particularly long time.

您可以使用类似的内容:

You could use something like:

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Trip")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.propertiesToFetch = ["id"]
do {
   if let results = try self.moc.fetch(fetchRequest) as? [[String:Any]] {
       let idSet = Set<Int32>(results.flatMap({ (dict) -> Int32? in
                return dict["id"] as? Int32
        }))
   }
 } catch {
     print("Error reading trips")
 }

现在,您可以轻松检查给定ID是否为新ID,并在需要时插入新行程:

Now you can easily check if a given id is new or not and insert a new trip if required:

for csvTrip in csvTrips {
    if let tripId = Int(csvTrip[0]) {
        if !idSet.contains(tripId) {
            trip = NSEntityDescription.insertNewObject(forEntityName: "Trip", into: context)
            trip.setValue(tripId, forKey: "id")
        }
     }
}

在我的测试中,这花费了1.35秒,将320,000个旅行ID加载到集合中,并花费了0.08秒创建了10,000个新旅行,同时检查了旅行ID是否包含在集合中.

In my test, this took 1.35 seconds to load 320,000 trips ids into a set and 0.08s to create 10,000 new trips whilst checking to see if the trip id was contained in the set.

这篇关于用Core Data插入/更新记录的最有效方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆