基于具有继承的相关对象中的属性获取NSManagedObjects?

时间:2013-12-05 23:30:26

标签: core-data nspredicate

我有一个相当复杂的CoreData数据模型,其实体继承自其他实体,我在执行谓词时遇到异常。例如:

    @"player.score > 1000";

其中:

    Player (abstract)
        - name
        - tags -> Tag

    LocalPlayer : Player
        - score
        - lives

    VirtualPlayer : Player
        - difficultyLevel


    Tag : NSManagedObject
        - name
        - color
        - player -> Player    

我理解为什么,Tag与Player有关系,而score是LocalPlayer的一个属性,因此它无效,因为它不在其他Player子类上。但我真的不想失去我的数据模型的层次结构。

是否有办法(子查询,可能?)将我的谓词限制为仅针对Tag:player->播放器关联中的LocalPlayer对象运行?有什么建议吗?

感谢。

2 个答案:

答案 0 :(得分:1)

如果您尝试使用此谓词执行获取请求,则无法执行此操作。谓词被编译为SQL语句,并在发送到后备数据库执行之前进行验证。有趣的是,Core Data在单个大型表中实现了继承。因此,SQL语句实际上不会失败并返回正确的结果。但是在Core Data谓词解析器执行之前失败了,它根据模型验证它。要解决此问题,请考虑将score属性提升为抽象类Player。也许,将其存储为NSNumber,这将允许nil值表示不相关(在VirtualPlayer个对象的情况下)。

你也可以撤销你的获取请求,获取得分为1000的所有本地玩家,然后列出所有标签:

NSSet* tags = [[moc executeFetchRequest:localPlayersRequest error:NULL] valueForKey:@"@distinctUnionOfSets.tags"];

但请注意,这不是最佳选择,您可以考虑预取tags关系以便更快地联合集。

答案 1 :(得分:0)

你不应该有这样的谓词。从概念角度来看,Player不能保证score。相反,您应该将请求的实体设置为LocalPlayer

在我看来,更好的方法是完全避免继承复杂性。如果您问题中的属性列表是详尽无遗的,我认为您最好将模型简化为Player实体以包含所有属性。你甚至可以添加一个布尔isVirtual来简化查询过滤器。

保持简单易读。你可能会“失去等级”,但你会“获得简单”。