Core data 基于继承相关对象中的属性获取NSManagedObject?

Core data 基于继承相关对象中的属性获取NSManagedObject?,core-data,nspredicate,Core Data,Nspredicate,我有一个相当复杂的CoreData数据模型,其中实体继承自其他实体,执行谓词时出现异常。例如: @"player.score > 1000"; 其中: Player (abstract) - name - tags -> Tag LocalPlayer : Player - score - lives VirtualPlayer : Player - difficul

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

    @"player.score > 1000";
其中:

    Player (abstract)
        - name
        - tags -> Tag

    LocalPlayer : Player
        - score
        - lives

    VirtualPlayer : Player
        - difficultyLevel


    Tag : NSManagedObject
        - name
        - color
        - player -> Player    
我理解为什么,标记和玩家有关系,分数是LocalPlayer上的一个属性,所以它无效,因为它不在其他玩家子类上。但我真的不想失去数据模型的层次结构

有没有办法(可能是子查询?)将谓词限制为仅针对标记:player->player relationship中的LocalPlayer对象运行?有什么建议吗


谢谢。

如果您试图使用此谓词执行提取请求,则不可能。谓词被编译为SQL语句,并在发送到后台数据库执行之前进行验证。有趣的是,核心数据在单个大表中实现继承。因此SQL语句实际上不会失败并返回正确的结果。但它在核心数据谓词解析器执行之前失败,该解析器根据其模型对其进行验证。为了克服这一点,考虑将<>代码> 属性推广到抽象类<代码>播放器< /代码>。也许,将其存储为
NSNumber
,这将允许使用
nil
值来指示不相关(在
VirtualPlayer
对象的情况下)

您还可以反向获取请求,获取所有得分为1000的本地玩家,然后获取所有标记的列表:

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

注意,这是不太理想的,你可以考虑预取<代码>标签< /代码>关系,以便更快的集合。

你不应该有这样的谓词。从概念的角度来看,
玩家
不一定有
分数
。相反,您应该将请求的实体设置为
LocalPlayer

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


保持简单易读。你可能会“失去层次结构”,但你会“变得简单”

感谢Leo,向下移动属性似乎是最简单的解决方案,我只是想避免它,以尽可能保持类更干净。我考虑按照您的建议反转提取,但是我想利用fetched results controller,而反转fetch会消除它通过跟踪更改提供的好处。这不是一个有效的解决方案,因为VirtualPlayers也可以被标记。我很感激您的回答,但这实际上会使事情更加复杂,并且会不必要地扰乱基类。