CoreData多对多关系NSPredicate Exceptions

时间:2010-04-02 08:52:22

标签: objective-c core-data nspredicate

我正在尝试模拟人/团队关系。这是一个多对多的关系,因为一个人可以属于多个团队,一个团队可以有多个人。正如文档所建议的,我创建了一个名为TeamMember的中间实体。我现在正在尝试运行查询以查看是否有人员列表,是否已存在已存在的团队,因此我不会在数据库中存储重复的团队

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity =
[NSEntityDescription entityForName:@"Team"
            inManagedObjectContext:[pm managedObjectContext]];
[request setEntity:entity];

NSPredicate *predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"ALL %K IN %@", @"teamMembers.person",  players];

玩家是我正在尝试搜索的NSSet人员

我遇到以下异常:

由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'不支持的谓词ALL teamMembers.person IN {(entity:Person; id:0x1334470; data:{

理想情况下,我希望它们完全匹配,而不仅仅是做一个IN。

非常感谢任何帮助

1 个答案:

答案 0 :(得分:5)

首先,看到你的数据模型会有所帮助,但我猜你正在做类似的事情:

Person <-->> TeamMember <<--> Team

我意识到你在文档中看到了这一点(由于未知的原因,这些文件往往使简单的事情复杂化),我不得不问;你为什么做这个?除非有特定于该TeamMember对象的数据,否则您可以这样做:

Person <<-->> Team

其次,你的谓词不正确,可能没必要。由于您已经拥有对此人的引用,因此您可以通过以下方式直接查询该人所属的团队:

NSSet *teams = [person valueForKeyPath:@"teamMembers.@distinctUnionOfSets.team"];

这将为您提供一组Team对象。但是,如果您删除了TeamMember对象,则可以使用以下方法简化此查询:

NSSet *teams = [person valueForKey@"teams"];

由于核心数据使用NSSet而不是NSArray,您甚至不需要担心此级别的重复,因为如果您尝试将同一个团队多次添加到该集合中,它将会被忽略了。

为了完善答案,你的谓词的问题是你不能在一个谓词中将IN和ALL混合在一起来对抗核心数据。这是一个已知的限制。因此,我建议采用上述方法。