【问题标题】:CoreData many-to-many relationship NSPredicate ExceptionsCoreData 多对多关系 NSPredicate 异常
【发布时间】:2010-04-02 08:52:22
【问题描述】:

我正在尝试为人/团队关系建模。这是多对多的关系,因为一个人可以属于多个团队,而一个团队可以有多个人。正如文档所建议的,我创建了一个名为 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];

players 是我试图搜索的人的 NSSet

我收到以下异常:

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

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

任何帮助将不胜感激

【问题讨论】:

    标签: objective-c core-data nspredicate


    【解决方案1】:

    首先,查看您的数据模型会有所帮助,但我猜您正在执行以下操作:

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

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

    Person <<-->> Team
    

    其次,您的谓词不正确并且可能是不必要的。由于您已经有了该人的引用,您可以通过以下方式直接查询该人所属的团队:

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

    这将为您返回一组 Team 对象。但是,如果您删除 TeamMember 对象,则可以通过以下方式简化此查询:

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

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

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

    【讨论】:

    • 感谢您的回复。是的,您对我的数据模型的猜测是正确的。我确实需要那个中间对象,因为我必须在 TeamMember 对象中存储一些额外的属性。我试图弄清楚是否有一种有效的方法可以让我使用 NSPredicate 执行以下操作:给定一个人员列表,找到一组仅包含这些人员的团队至于你最后的评论。这可能只是我对 NSPredicates 的基本了解,但我并没有将任何和所有混合在一起,是吗?还是将 IN 与集合一起使用会以某种方式翻译成 ANY?再次感谢您对此的帮助。
    • 我的意思是 ALL 和 IN。更正了那个错字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多