Swift Core Data:基于子实体谓词的FetchRequest实现问题
解决Core Data一对多关系下子实体过滤问题
你的代码存在两个明显问题:
- 类型不匹配:声明的
scans是FetchRequest<Scan>,但赋值的却是FetchRequest<Category>,类型完全不兼容 - 谓词逻辑错误:
scans.isSent = %d的作用是筛选出包含至少一个isSent=true的Scan的Category,而不是过滤每个Category下的Scan子实体
下面是两种可行的解决思路:
思路一:获取所有Category后在内存中过滤子实体
适合数据量不大的场景,直接获取完整的Category集合,再对每个Category的scans进行过滤:
// 定义Category的FetchRequest let categoriesRequest: FetchRequest<Category> = FetchRequest( entity: Category.entity(), sortDescriptors: [] ) // 使用时过滤每个Category的scans for category in try! context.fetch(categoriesRequest) { let validScans = category.scans.filter { $0.isSent } // 处理过滤后的validScans }
思路二:直接查询符合条件的Scan实体
如果业务更关注Scan数据,可以直接查询isSent=true的Scan,再通过关联属性获取对应的Category:
// 定义Scan的FetchRequest,直接过滤isSent=true的记录 let scansRequest: FetchRequest<Scan> = FetchRequest( entity: Scan.entity(), sortDescriptors: [], predicate: NSPredicate(format: "isSent = %d", true) ) // 获取结果后关联到Category for scan in try! context.fetch(scansRequest) { let category = scan.category // 处理category和当前scan }
需要注意:Core Data无法通过Category的FetchRequest直接让返回的Category实例的scans集合自动过滤出符合条件的子实体,因为实体的关联集合默认会加载所有关联对象。因此上述两种方式是最直接的解决方案。
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

