具有多个谓词的核心数据

发布于 2024-10-19 09:22:41 字数 1236 浏览 3 评论 0原文

对于这样的关系:

TagGroups<---->>Tags<<---->>Object

一个Object有标签,标签可以通过tagGroups进行分组。

我有一个对象,我想知道它的标签所属的所有标签组。

为了构建谓词,我首先尝试了以下格式字符串:

(SELF 是一个 TagGroup)

NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN SELF.tags.objects" , object];

这失败了,因为集合没有像 Key-ValueCoding 那样被遍历。

经过一番研究,我发现了几个解释 SUBQUERY 的问题

核心数据,尝试使用 NSPredicate 过滤 toMany 关系集,但收到“此处不允许使用 to-many key”错误

Core data to-many NSPredicate with AND

这些似乎是解决方案的一部分,但与这些问题不同,我没有测试类似于“tag.name”的值,但属于集合内的成员资格。

因此,考虑到这一点,我尝试了以下方法:

NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN SUBQUERY(SELF.tags, $eachTag,$eachTag.object)" , object];

哪个无法解析(我也尝试了其他一些变体,但未成功)

关于如何正确构造此格式字符串有什么想法吗?

更新:

也从另一个方向尝试过:

NSPredicate* p = [NSPredicate predicateWithFormat:@"ALL SUBQUERY(%@.tags,$eachTag,$eachTag.tagGroup)" , anObject];

For a relationship like this:

TagGroups<---->>Tags<<---->>Object

An Object has tags, tags can be grouped by tagGroups.

I have an object, and I want to know all of the TagGroups its Tags belong to.

To construct he predicate, I first tried the following format string:

(SELF is a TagGroup)

NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN SELF.tags.objects" , object];

This fails because sets are not traversed ala Key-ValueCoding.

After some research I have found several questions explaining SUBQUERY

Core Data, try to use NSPredicate to filter a toMany relationship set but get the "to-many key not allowed here" error

Core data to-many NSPredicate with AND

These seem to be part of the solution, but unlike these questions I am not testing for a value like "tag.name", but membership within the collection.

So with that in mind I tried this:

NSPredicate* p = [NSPredicate predicateWithFormat:@"%@ IN SUBQUERY(SELF.tags, $eachTag,$eachTag.object)" , object];

Which fails to parse (I tried a few other variants unsuccessfully as well)

Any ideas on how to construct this format string properly?

Update:

Also tried it from the other direction:

NSPredicate* p = [NSPredicate predicateWithFormat:@"ALL SUBQUERY(%@.tags,$eachTag,$eachTag.tagGroup)" , anObject];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

∞梦里开花 2024-10-26 09:22:41

如果您“有一个对象”,即您有一个特定的托管对象,其实体是Object,那么您不需要谓词。您只需要走关系关键路径即可。

这是一个使用字典实现的示例,它的工作方式与托管对象相同。

NSDictionary *tagGroup1=[NSDictionary dictionaryWithObjectsAndKeys:@"tagGroupOne",@"name",@"tagGroup1",@"theValue",nil];
NSDictionary *tagGroup2=[NSDictionary dictionaryWithObjectsAndKeys:@"tagGroupTwo",@"name",@"tagGroup2",@"theValue",nil];
NSDictionary *tag1=[NSDictionary dictionaryWithObject:tagGroup1 forKey:@"tagGroup"];
NSDictionary *tag2=[NSDictionary dictionaryWithObject:tagGroup2 forKey:@"tagGroup"];

NSSet *tags=[NSSet setWithObjects:tag1,tag2,nil];

NSDictionary *objD=[NSDictionary dictionaryWithObjectsAndKeys:tags,@"tags",nil];
NSLog(@"tagGroup names=%@",[objD valueForKeyPath:@"tags.tagGroup.name"]);
NSLog(@"tagGroup objects=%@",[objD valueForKeyPath:@"tags.tagGroup"]);

...输出:

tagGroup names={(
    tagGroupTwo,
    tagGroupOne
)}

tagGroup objects={(
        {
        name = tagGroupTwo;
        theValue = tagGroup2;
    },
        {
        name = tagGroupOne;
        theValue = tagGroup1;
    }
)}

所以,实际上您所需要的只是一行:

NSSet *tagGroups=[anInstanceOfObject valueForKeyPath:@"tags.tagGroup"];

这就是键值编码的力量。

仅当您尝试获取与具有特定属性值的 TagGroup 存在关系的对象时,才需要子查询。

If you "have an object" i.e. you have a particular managedObject whose entity is Object then you don't need a predicate. You just need to walk the relationship keypath.

Here is an example implemented with dictionaries by it works the same way with a managed object.

NSDictionary *tagGroup1=[NSDictionary dictionaryWithObjectsAndKeys:@"tagGroupOne",@"name",@"tagGroup1",@"theValue",nil];
NSDictionary *tagGroup2=[NSDictionary dictionaryWithObjectsAndKeys:@"tagGroupTwo",@"name",@"tagGroup2",@"theValue",nil];
NSDictionary *tag1=[NSDictionary dictionaryWithObject:tagGroup1 forKey:@"tagGroup"];
NSDictionary *tag2=[NSDictionary dictionaryWithObject:tagGroup2 forKey:@"tagGroup"];

NSSet *tags=[NSSet setWithObjects:tag1,tag2,nil];

NSDictionary *objD=[NSDictionary dictionaryWithObjectsAndKeys:tags,@"tags",nil];
NSLog(@"tagGroup names=%@",[objD valueForKeyPath:@"tags.tagGroup.name"]);
NSLog(@"tagGroup objects=%@",[objD valueForKeyPath:@"tags.tagGroup"]);

... which outputs:

tagGroup names={(
    tagGroupTwo,
    tagGroupOne
)}

tagGroup objects={(
        {
        name = tagGroupTwo;
        theValue = tagGroup2;
    },
        {
        name = tagGroupOne;
        theValue = tagGroup1;
    }
)}

So, really all you need is a line like:

NSSet *tagGroups=[anInstanceOfObject valueForKeyPath:@"tags.tagGroup"];

That's the power of key-value coding.

You would only need a subquery if you were trying to fetch Objects that had a relationship to a TagGroup with a particular attribute value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文