CoreData 中的递归获取

Posted

技术标签:

【中文标题】CoreData 中的递归获取【英文标题】:Recursive fetch in CoreData 【发布时间】:2019-11-30 11:21:07 【问题描述】:

我有一个简化为这样的数据结构:

所以一个文件夹可以包含多个文件夹或sn-ps,每个sn-p都是一个文件夹的一部分。 我想获取给定文件夹中或特定文件夹子文件夹中的所有片段。

第一种情况适合我,但我无法正确处理第二种情况。

为了更清楚,这里举个例子:

当我选择文件夹 C 时,我想获取 Snippet 3,但当我选择文件夹 B 或文件夹 A 时,我想获取 Snippet 1、Snippet 2 和 Snippet 3。

这是我目前拥有的:

class Store 
...
    func snippetsFetchRequest() -> NSFetchRequest<Snippet> 
        let fetch: NSFetchRequest<Snippet> = Snippet.fetchRequest()
        fetch.returnsObjectsAsFaults = false
        fetch.relationshipKeyPathsForPrefetching = ["folder", "tags"]
        fetch.sortDescriptors = [NSSortDescriptor(key: "updateDate", ascending: false)]
        return fetch
    
...



let context = PersistenceManager.shared.mainContext
let store = SnippetStore(context: context)
fetchedResultsController = NSFetchedResultsController(fetchRequest: store.snippetsFetchRequest(),
        managedObjectContext: context,
        sectionNameKeyPath: nil,
        cacheName: nil)
fetchedResultsController.fetchRequest.predicate = NSPredicate(format: "folder == %@", selectedFolder)
do 
    try fetchedResultsController.performFetch()
 catch 
    ...

但这只会获取作为给定/选定文件夹的直接子级的 sn-ps。

我有什么办法可以通过仍然使用NSFetchedResultsController来解决我的问题?

【问题讨论】:

这看起来有点像复合设计模式,你可以在代码中解决这个问题,方法是使用一个方法 allSnippets 获取 snippets 并将其与调用 allSnippets 的所有结果合并children 是的,我也这么认为。我想我可以通过获取所有 sn-ps 然后应用一些过滤器逻辑来解决它,分别遍历孩子。但是我问自己 NSPredicates 是否有一些内置功能。 NSFetchedResultsController 或通过更新我可以使用的底层模型架构,而不是删除我的 FetchedResultsController 并自己实现逻辑。 我现在看到我忘了说allSnippets 应该是Folder 类中的一个方法。 当然,我已经在可以利用的文件夹上建立了 sn-ps 关系。我想如果表达这种 FetchRequest 没有聪明的方法,这将是要走的路。 【参考方案1】:

你的数据结构是错误的。人们倾向于认为数据结构对给定信息具有“正确性”;你想尽可能地“模拟”现实。这是错误的。您的模型只有在为您的特定应用程序提供价值的范围内才有价值。

在这种情况下,如果您想获取文件夹的所有死者,最好建立一个关系来表示它。您可以在添加对象时设置死者和祖先的多对多关系。如果您需要更多属性进行过滤或排序,您应该添加它们,即使这些属性理论上可以从当前树模型派生。只需确保它们保持同步即可。

【讨论】:

以上是关于CoreData 中的递归获取的主要内容,如果未能解决你的问题,请参考以下文章

如何修复尝试使用 coredata 递归调用 -save 错误?

coredata获取请求中的日期比较?

如何从coredata中的实体获取过滤数据

SwiftUI 中的 CoreData:如何清楚地获取属性?

从 CoreData 中的 TextField 保存和获取

根据 coredata 中的属性名称获取唯一对象