CoreData:使用 NSPredicate 过滤一对多对多关系(此处不允许错误对多键)

Posted

技术标签:

【中文标题】CoreData:使用 NSPredicate 过滤一对多对多关系(此处不允许错误对多键)【英文标题】:CoreData: Using NSPredicate to filter one to many to many relationship (error to-many key not allowed here) 【发布时间】:2015-02-13 08:44:20 【问题描述】:

我有 coreData 模型:

我正在尝试验证电影的时间表是否与电影和剧院相匹配,但我收到错误“此处不允许使用对多键”

这是我的代码:

NSManagedObjectContext *moc = [self managedObjectContext];
    NSEntityDescription *timeDescription = [ NSEntityDescription entityForName:@"Schedules" inManagedObjectContext:moc];
    NSPredicate *timePredicate  = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
    NSPredicate *moviePredicate = [NSPredicate predicateWithFormat:@"ANY movie.nameOfMovie CONTAINS[cd] %@", _movie];
    NSPredicate *theatersPredicate = [NSPredicate predicateWithFormat:@"movie.theaters.nameOfTheater == %@", _theaterName];
    NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[timePredicate,moviePredicate,theatersPredicate]];

    NSFetchRequest *request = [NSFetchRequest new];
    request.predicate = compoundPredicate;
    request.entity = timeDescription;
    NSError *error = nil;

    NSArray *result = [moc executeFetchRequest:request error:&error];

如果我只使用以下谓词:

NSPredicate *timePredicate  = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *moviePredicate = [NSPredicate predicateWithFormat:@"ANY movie.nameOfMovie CONTAINS[cd] %@", _movie];

我可以匹配日程安排和电影,但我的问题是我如何才能匹配日程安排、电影和剧院,你们中的任何人都知道我做错了什么吗?

非常感谢您的帮助

【问题讨论】:

为什么你不只是在你的另一个问题中用 SUBQUERY 扩展我给你的答案的谓词?如果它工作正常,只需在时间中添加一个进一步的 AND 条件 有点重复?既然你遇到了同样的问题***.com/questions/28436816/…? @geo,我遇到的问题是当我的实体是“计划”到“剧院”时如何返回。 NSPredicate *theatersPredicate = [NSPredicate predicateWithFormat:@"movie.theaters.nameOfTheater == %@", _theaterName]; . @Lame,这是完全不同的问题 【参考方案1】:

您收到“此处不允许使用多对多键”错误,因为在您的 theatersPredicate“电影”中是一对多关系。与您的 moviePredicate 进行比较,因为它使用“ANY”关键字,所以可以正常工作。

因此,您可能很想将“ANY”添加到您的theatersPredicate。这将起作用(即编译并运行正常),但我认为不会为您提供您正在寻找的结果:它将显示“(任何电影的电影名称匹配)和(任何电影的 nameOfTheatre 匹配)”。但在每种情况下,它可能是不同的电影。

我认为您想要的是“(电影名称匹配且 nameOfTheatre 匹配)的任何电影”。为此,请使用 SUBQUERY:

NSPredicate *timePredicate  = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *movieAndTheaterPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(movie, $x, $x.nameOfMovie CONTAINS[cd] %@ AND $x.theaters.nameOfTheater == %@).@count > 0", _movie, _theaterName];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[timePredicate,movieAndTheaterPredicate]];

【讨论】:

抱歉,印刷错误(谓词中多余的“)现已被删除。

以上是关于CoreData:使用 NSPredicate 过滤一对多对多关系(此处不允许错误对多键)的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate,CoreData 中的空格。如何修剪谓词?

如何使用 NSPredicate 从 CoreData 中删除选定数量的行?

在 Swift 中使用 NSPredicate 显示 CoreData 的结果

在 Swift 中使用 NSPredicate 对 CoreData 结果进行排序

使用 NSPredicate 根据数组属性过滤 CoreData 项列表

CoreData NSPredicate