帮助 CoreData 制作 NSPredicate - 递归搜索
我正在将 CoreData 用于 iPhone 项目,但我在尝试构建谓词时陷入困境。
我的核心数据实体是
Folder
parent - Point to the folder class parent, can be null and is one to one.
secure - An enum that holds the security type.
我遇到的问题是我试图使其不显示安全文件夹中的任何文件夹。
现在我的谓词看起来像这样。
NSPredicate *pred = [NSPredicate predicateWithFormat:@"secure = $@ AND (parent = %@ OR parent.secure = %@)",[NSNumber numberWithInteger:kNoSecurity], [NSNull null], [NSNumber numberWithInteger:kNoSecurity]];
当我只有像folder1这样的链时,这可以找到 -> folder2 和folder1 是安全的。但如果我有folder1 ->文件夹2 -> folder3(folder2 和folder3 不安全)。文件夹 3 被返回,因为我只检查了上一级。有没有办法让谓词对整个链进行检查?
谢谢。
I am using CoreData for an iPhone project and I am stuck trying to build a predicate.
My core data entity is
Folder
parent - Point to the folder class parent, can be null and is one to one.
secure - An enum that holds the security type.
The problem I have is that I am trying to make it so I don't show any folder that are in a secure folder.
Right now my predicate looks something like this.
NSPredicate *pred = [NSPredicate predicateWithFormat:@"secure = $@ AND (parent = %@ OR parent.secure = %@)",[NSNumber numberWithInteger:kNoSecurity], [NSNull null], [NSNumber numberWithInteger:kNoSecurity]];
This works find when I only have a chain like folder1 -> folder2 and folder1 is secure. But if I have folder1 -> folder2 -> folder3 (folder2 and folder3 are not secure). Folder3 gets returned because I only check one level up. Is there a way to get the predicate to do the check for a entire chain?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您无法在谓词中递归地遍历关系,因为键路径仅描述抽象实体之间的关系,而不是实际包含数据的具体的、活动的托管对象之间的关系。实体图可以非常简单,但在运行时填充时会生成极其复杂的活动对象图。您无法使用简单的键路径从逻辑上捕获该实时图形的复杂性。
在本例中,您有一个
Folder
实体,它与其自身有一个称为parent
的关系,并且有一个secure
属性。因此,密钥路径最多只能描述路径parent.secure
的这两个属性。您无法创建parent.parent.secure
的键路径,因为实体图中实际上不存在这样的关系。这样的路径有时仅存在于活动对象图中。从逻辑上讲,不可能对一条可能存在或不存在的路径进行硬编码,具体取决于任何给定时间的数据细节。在这种情况下,创建自定义 NSManagedObject 子类的能力真正派上用场。您的
Folder
实体不必只是哑数据,您可以向它们添加行为,以便每个对象都可以访问自己的状态并根据需要返回不同的数据。在这种情况下,我建议添加一个名为
hasSecureAncestor
之类的瞬态布尔属性。然后创建一个自定义 getter 方法,例如:然后创建一个谓词来测试“hasSecureAncestor==YES”。自定义访问器将遍历任意深度的递归关系,寻找安全的祖先。
You can't recursively walk relationships in predicates because keypaths only describe the relationship between the abstract entities and not the concrete, living managed objects that actually contain the data. An entity graph can be very simple yet generate a vastly complex graph of live objects when populated at runtime. You can't logically capture the complexity of that live graph with a simple keypath.
In this case, you have a
Folder
entity which has a relationship to itself calledparent
and an attribute ofsecure
. Therefore, a keypath can only describe at most those two properties with pathparent.secure
. You can't create a keypath ofparent.parent.secure
because no such relationship actually exists in the entity graph. Such a path only exist sometimes in the live object graph. It would be logically impossible to hard code a path that might or might not exist depending on the particulars of the data at any given time.This type of situation is where the ability to create customized NSManagedObject subclasses really comes in handy. Your
Folder
entites don't have to be just dumb data, you can add behaviors to them so that each object can access its own state and return different data as needed.In this case, I would recommend adding a transient boolean property named something like
hasSecureAncestor
. Then create a custom getter method like:Then just create a predicate to test for "hasSecureAncestor==YES". The custom accessor will walk an arbitrarily deep recursive relationship looking for a secure ancestor.
为什么不直接使用
kNoSecurity
获取所有文件夹实体?Why not just grab all Folder entities with
kNoSecurity
?回顾一下这段关系怎么样:
How about going back up through the relationship: