我有一个相当复杂的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对象运行?有什么建议吗?
感谢。
答案 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
来简化查询过滤器。
保持简单易读。你可能会“失去等级”,但你会“获得简单”。