CoreData:查询一对多关系

时间:2015-05-12 17:24:46

标签: ios objective-c cocoa core-data nspredicate

我有一个这样的核心数据模型:

enter image description here

我试图查询显示特定日程影院的所有电影。

但我无法弄清楚如何使用NSPredicate进行此查询。

我试过了:

NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY (movies, $x, $x.movies.showTimes == %@ AND  $x.movies.theater.nameOfTheater == %@).@count >0", showTime, theater];

但没有奏效。你们中的任何人都知道我做错了什么?

我真的很感谢你的帮助

1 个答案:

答案 0 :(得分:1)

我假设您所声明的目标(" ...查询显示具有特定时间表的剧院的所有电影"),NSFetchRequest的实体为Movies。如果是这样,您使用的属性和关系名称都应该相对于该实体。因此,剧院名称将由theaters.nameOfTheater提供,节目时间将为showTimes.showTimes。由于给定Schedules有很多Movie,如果showTimes.showTimes中的任何一个符合您的要求,您的谓词就需要选择一部电影。因此编写谓词的一种方法是:

NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"theaters.nameOfTheater == %@ AND (ANY showTimes.showTimes == %@)", theater, showTime];

或者,可以将ANY子句重写为SUBQUERY:

NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"theaters.nameOfTheater == %@ AND SUBQUERY(showTimes, $x, $x.showTimes == %@).@count > 0", theater, showTime];

作为更广泛的建议,我会对属性和实体的名称进行一些更改;它将有助于使事情更清楚:

  1. 实体名称通常应该是单数,因此Movie不是MoviesTheatre不是TheatresSchedule不是Schedules
  2. 同样,关系的名称应该反映它们是一对一还是多对。因此,Movie实体应该具有theatre关系,因为它是一对一,并且Schedule实体应该具有movies的关系,因为它是多对的。
  3. 最后,我认为您可以改进您的数据模型。目前,每部电影只能有一个剧院。在实践中,我会想象一部电影将在不止一个剧院上映!就个人而言,我会有这样的模型:

    Data Model

    因此,每个Schedule只涉及一个Movie和一个Theater。但每个Theater都有很多showings,而每个Movie都有很多screenings。使用此模型,满足您的查询的谓词将是:

    NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(screenings, $x, $x.theater.nameOfTheater == %@ AND $x.showTime == %@).@count > 0", theater, showTime];