CoreData - 按关系批量获取对象以获得更好的性能
Posted
技术标签:
【中文标题】CoreData - 按关系批量获取对象以获得更好的性能【英文标题】:CoreData - fetch objects by relationship in a batch for better performance 【发布时间】:2017-08-08 16:26:52 【问题描述】:简介
只要有可能,我就会尝试在核心数据中使用查找或创建模式。当我为一组可通过 id 识别的项目执行此操作时(无论是 string 还是 int),我会分批执行此操作(因为反对对每个项目进行一次提取):
let itemIDs = Set(items.map $0.id )
let fetchRequest = NSFetchRequest<E>(entityName: E.entityName())
fetchRequest.predicate = NSPredicate(format: "id IN %@", itemIDs)
let foundObjects = try! context.fetch(fetchRequest)
问题
我有一个无法通过 id 而是通过它与其他实体的关系来识别的实体
ItemPosition
===============
attributes:
- position
---------------
relationships:
- endpoint: N:1
- item: N:1
这里的唯一键是endpoint
和item
的组合。
对于这个实体,我对每个项目进行一次提取,因为我不知道如何批量进行:
var foundObjects: [ItemPosition] = []
for item in items
let fetchRequest = NSFetchRequest<E>(entityName: E.entityName())
fetchRequest.predicate = NSPredicate(format: "item = %@ AND endpoint = %@", item, endpoint)
let results = try! context.fetch(fetchRequest)
if let position = results.first
foundObjects.append(position)
这不是最优的,因为它会针对每个项目访问 SQL 数据库,我想避免这种情况。
问题
有没有办法通过多个关系批量获取对象?类似于上面提到的NSPredicate(format: "id IN %@", itemIDs)
?
【问题讨论】:
是否考虑过对实体进行初始提取,然后在返回的对象数组上调用.filter
?这将允许您删除您想要或不需要的对象。
【参考方案1】:
我可以想到几种方法来做到这一点,但都不是特别优雅。您可以使用复合 OR 谓词:
var predicates: [NSPredicate] = []
for item in items
predicates.append(NSPredicate(format: "item = %@ AND endpoint = %@", item, endpoint))
let compoundPredicate = NSCompoundPredicate.init(orPredicateWithSubpredicates: predicates)
let results = try! context.fetch(compoundPredicate)
或者您可以通过附加端点和项目 ID 为 ItemPosition 对象生成一个 ID,然后通过它获取?
【讨论】:
以上是关于CoreData - 按关系批量获取对象以获得更好的性能的主要内容,如果未能解决你的问题,请参考以下文章