所以,我只是真正享受Core Data,并开始将其集成到我正在开发的应用程序中。但是,我遇到了一个问题,我没有看到任何明显的解决方案,这让我觉得Core Data不是正确的工具。情况就是这样:我有一棵Node
的树,每棵都有或没有孩子。可能有任意多个根Node
。我已经使用to-many关系(从Node
到Node
s)将数据模型与一对一关系放在一起。一切都很好。
现在,每个Node
也与Record
具有多对多的关系,这与Node
之间的关系也是一对一的。{1}}。我想要做的是找到所有具有特定布尔属性设置为true的Record
,并且 位于 之下的某个Node
。在我使用Core Data之前,这非常简单 - 我只是走在树上。然而,这是耗时的,我希望Core Data能给我一个方法来制作一个获取请求,它可以快速获取我想要的所有Record
个。如果我知道我想要检查的最大深度,我可以很容易地看到如何(半)这样做,但如果我想要一直走下去怎么办?如果不是所有Node
都有孩子会怎么样?
我应该像往常一样走树吗?
NSFetchRequest
是否能够执行此类任务?
答案 0 :(得分:2)
这不是核心数据问题,而是图形问题。你必须做同样的搜索。但是,CoreData可以允许您在对象中出错。所以,你有几个选项,其中两个是
1)走树。您应该能够使用与内存树一样的完全相同的算法。 CoreData应该只是对象中的错误。除非你有一棵非常深的树,否则你应该没事。
2)对每条记录中的父关系进行编码。更新树时会进行大量更新,但提取速度会更快。
以下内容可以转换为NSCompoundPredicate并指定为fetch谓词... Docs说它适用于CoreData,但不适用于sqllite - 试试吧。
NSPredicate *nodePredicate = [NSPredicate predicateWithFormat:@"field = %@", value];
// Use nodePredicate to find ones that match the ones you want to find
// Then use a block predicate to see if the parent is there.
NSArray *potential = [context executeFetchRequest:fetchRequest error:&error];
if (!error) {
NSPredicate *parentPredicate = [NSPredicate predicateWithBlock:^BOOL(id obj, NSDictionary *bindings) {
Node *node = obj;
while (node) {
if ([node.parent.nodeId isEqualToString:targetId) return YES;
node = node.parent;
}
return NO;
}];
NSArray *foundNodes = [potential filteredArrayUsingPredicate:parentPredicate];
}