用于多对多关系的 NSPredicate 过滤器
Posted
技术标签:
【中文标题】用于多对多关系的 NSPredicate 过滤器【英文标题】:NSPredicate filter for many-to-many-to-many relationships 【发布时间】:2011-09-29 04:40:08 【问题描述】:我对使用 NSPredicate 还很陌生,但我遇到了一个有点复杂的问题,我不太确定解决方案的最佳方法。
我正在尝试为一个名为 Instrument 的实体构建一个过滤器,它可以与许多程序一起使用。反过来,程序与一种或多种疾病有关。疾病与许多程序有关,仪器可用于多个程序。换句话说,我有以下多对多的关系:
Instruments <-> Procedures <-> Diseases
我想做的是使用 Disease.title 过滤仪器。在一个简单而神奇的世界里,这就像
//where predicate is used on the Instruments array
[NSPredicate predicateWithFormat:@"(procedures.diseases.title == %@)", diseaseTitleString];
逐段浏览(有一些错别字和命名错误),我发现过滤器知道Procedures和Diseases的字段足以告诉我“diseaseTypes”不是procedures上的字段,而“name”是不是疾病领域。天真让我希望这个简单的谓词能奏效。
我什么也得不到。
我也尝试过使用(ALL procedures.diseases.title == %@)
,但这也不起作用。
我已经看到了一些关于子谓词的事情,但没有什么真正让我觉得有效或对我很有意义的东西。
基本上我想获取列表:
NSArray *instruments = [[NSArray alloc] init];
for (Disease *disease in Diseases)
if ([disease.title isEqualToString:titleString])
for (Procedure *procedure in disease.procedures)
for (Instrument *instrument in procedure.instruments)
if (![instruments containsObject:instrument])
[instruments addObject:instrument];
现在,我正在使用这种方法来获取一个可以基于其他谓词进行过滤的数组,它工作正常,但它很难看,我觉得有一种更好、更清洁的方法来过滤它。谁能帮助我了解 NSPredicate 设计的更精细用途?
【问题讨论】:
【参考方案1】:在上面的谓词中,将双等号替换为单等号。还要添加一个“ANY”子句。最后,去掉括号。所以你将拥有:
[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@", diseaseTitleString];
一般来说,我发现处理复杂谓词的好方法是使用子谓词构建它们。
所以,你开始:
NSMutableArray *subpredicates = [NSMutableArray array];
然后一点一点地添加子谓词:
[subpredicates addObject:
[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@",
diseaseTitleString]]
[subpredicates addObject:anotherPredicate etc];
最后,创建你的“and”或“or”谓词,例如:
NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
【讨论】:
这里有一些很好的提示,但该谓词仍然返回一个空数组。我的其他子谓词工作正常,但这个多对多的仍然不工作,但应该等同于我上面代码中的循环构建集合。[instrumentFilters addObject:[NSPredicate predicateWithFormat:@"ANY procedures.diseases.title = %@", filterValue]];
然后我做了一个与其他过滤器一起工作的复合。我还有什么遗漏吗?
如果在没有 and 复合的情况下运行它会发生什么?
仅使用该谓词(无复合词)运行过滤器仍然不会返回任何内容。 :(
嗯。你能打开 .sqlite 文件并运行等效的 SQL 查询吗?剪切并粘贴疾病标题。另外,确认没有尾随空格等。
@MaxMacLeod 嗨,Max,很好的答案,也许你能帮帮我。我的关系 Object>addresses>phones 我需要检查 phones.tel 是否包含我的电话号码,我尝试 [NSPredicate predicateWithFormat:@"ANY addresses.phones.tel = %@", searchWord]
但我收到错误 @ 987654327@,你能给点建议吗?谢谢!以上是关于用于多对多关系的 NSPredicate 过滤器的主要内容,如果未能解决你的问题,请参考以下文章