user2924482
user2924482

Reputation: 9140

CoreData: Query to one-to-many-to-many relationship

I have a core data model like this:

enter image description here

and I'm trying to query all the movies showing a theater with particular schedule.

But I can not figure out how can I this query with NSPredicate.

I tried this:

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

but didn't work. Any of you knows what I'm doing wrong?

I'll really appreciate your help

Upvotes: 3

Views: 723

Answers (1)

pbasdf
pbasdf

Reputation: 21536

I'm assuming from your stated objective ("... query all the movies showing a theater with particular schedule") that the entity for your NSFetchRequest is Movies. If so, the attribute and relationship names you use should all be relative to that entity. Hence the theatre name will be given by theaters.nameOfTheater and the show times will be showTimes.showTimes. Because there are many Schedules for a given Movie, your predicate needs to select a movie if ANY of the showTimes.showTimes match your requirement. So one way to write the predicate would be:

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

Alternatively, the ANY clause can be rewritten as a SUBQUERY:

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

As a broader recommendation, I would make some changes the names of your attributes and entities; it will help to make things clearer:

  1. Entity names should generally be singular, so Movie not Movies, Theatre not Theatres and Schedule not Schedules.
  2. Likewise the names of relationships should reflect whether they are to-one or to-many. So the Movie entity should have a relationship theatre since it is to-one, and the Schedule entity should have a relationship movies since it is to-many.

Finally, I think you could improve your data model. Currently, each Movie can have only one Theater. In practice, I would imagine that a movie will be shown at more than one theater! Personally, I would have a model like this:

Data Model

So each Schedule relates to only one Movie and one Theater. But each Theater has many showings, and each Movie has many screenings. Using this model, the predicate to meet your query would be:

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

Upvotes: 1

Related Questions