CoreData:查询一对多对多关系
CoreData: Query to one-to-many-to-many relationship
我有一个这样的核心数据模型:
我正在尝试查询放映具有特定时间表的剧院的所有电影。
但我不知道如何使用 NSPredicate 进行查询。
我试过这个:
NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY (movies, $x, $x.movies.showTimes == %@ AND $x.movies.theater.nameOfTheater == %@).@count >0", showTime, theater];
但没用。你们有谁知道我做错了什么吗?
非常感谢你的帮助
我假设根据您陈述的 objective(“...查询放映具有特定时间表的剧院的所有电影”),您的 NSFetchRequest 的实体是 Movies
。如果是这样,您使用的属性和关系名称都应该与该实体相关。因此,剧院名称将由 theaters.nameOfTheater
给出,放映时间将为 showTimes.showTimes
。因为对于给定的 Movie
有很多 Schedules
,如果任何 showTimes.showTimes
符合您的要求,您的谓词需要 select 一部电影。因此,编写谓词的一种方法是:
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];
作为更广泛的建议,我将对您的属性和实体的名称进行一些更改;这将有助于使事情更清楚:
- 实体名称通常应为单数,因此
Movie
不是 Movies
,Theatre
不是 Theatres
,Schedule
不是 Schedules
。
- 同样,关系的名称应该反映它们是一对一还是一对多。所以 Movie 实体应该有关系
theatre
因为它是一对一的,而 Schedule 实体应该有关系 movies
因为它是一对多的。
最后,我认为您可以改进数据模型。目前,每部电影只能有一个剧院。实际上,我可以想象一部电影将在多个影院放映!就个人而言,我会有这样的模型:
所以每个 Schedule
只与一个 Movie
和一个 Theater
相关。但是每个Theater
有很多showings
,每个Movie
有很多screenings
。使用此模型,满足您的查询的谓词将是:
NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(screenings, $x, $x.theater.nameOfTheater == %@ AND $x.showTime == %@).@count > 0", theater, showTime];
我有一个这样的核心数据模型:
我正在尝试查询放映具有特定时间表的剧院的所有电影。
但我不知道如何使用 NSPredicate 进行查询。
我试过这个:
NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY (movies, $x, $x.movies.showTimes == %@ AND $x.movies.theater.nameOfTheater == %@).@count >0", showTime, theater];
但没用。你们有谁知道我做错了什么吗?
非常感谢你的帮助
我假设根据您陈述的 objective(“...查询放映具有特定时间表的剧院的所有电影”),您的 NSFetchRequest 的实体是 Movies
。如果是这样,您使用的属性和关系名称都应该与该实体相关。因此,剧院名称将由 theaters.nameOfTheater
给出,放映时间将为 showTimes.showTimes
。因为对于给定的 Movie
有很多 Schedules
,如果任何 showTimes.showTimes
符合您的要求,您的谓词需要 select 一部电影。因此,编写谓词的一种方法是:
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];
作为更广泛的建议,我将对您的属性和实体的名称进行一些更改;这将有助于使事情更清楚:
- 实体名称通常应为单数,因此
Movie
不是Movies
,Theatre
不是Theatres
,Schedule
不是Schedules
。 - 同样,关系的名称应该反映它们是一对一还是一对多。所以 Movie 实体应该有关系
theatre
因为它是一对一的,而 Schedule 实体应该有关系movies
因为它是一对多的。
最后,我认为您可以改进数据模型。目前,每部电影只能有一个剧院。实际上,我可以想象一部电影将在多个影院放映!就个人而言,我会有这样的模型:
所以每个 Schedule
只与一个 Movie
和一个 Theater
相关。但是每个Theater
有很多showings
,每个Movie
有很多screenings
。使用此模型,满足您的查询的谓词将是:
NSPredicate *moviesPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(screenings, $x, $x.theater.nameOfTheater == %@ AND $x.showTime == %@).@count > 0", theater, showTime];