CoreData: Querying One-to-Many Relationships

I have a basic data model:

enter image description here

and I am trying to request all films showing theater with a specific schedule.

But I cannot figure out how I can fulfill this request using NSPredicate.

I've tried this:

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

      

but doesn't work. Does any of you know what I am doing wrong?

I will be very grateful for your help.

+3


source to share


1 answer


I am assuming from your stated purpose ("... to request all movies showing theater on a specific schedule") that the object is for your NSFetchRequest Movies

. If so, the names of the attributes and relationships you are using must refer to this object. Therefore, the name of the theater will be indicated theaters.nameOfTheater

, and the time of the show will be showTimes.showTimes

. Since Movie

there are many for a given Schedules

, your predicate needs to select a movie if ANY of them showTimes.showTimes

matches your requirement. So one way to write a predicate is:

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

      

Alternatively, ANY's clause can be rewritten as 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 to the names of your attributes and entities; this will help make things clearer:



  • Entity names usually have to be singular, so Movie

    not Movies

    , Theatre

    not Theatres

    and Schedule

    not Schedules

    .
  • Likewise, the names of relationships should reflect whether they are one or to many. So the Movie object must have a relationship Theatre

    , since it is one, and the Schedule object must have a relationship Movies

    , since it is for many.

Finally, I think you could improve your data model. Currently, there can only be one theater per film. In practice, I would assume the film will be shown in more than one theater! Personally, I would have a model like this:

Data Model

So each Schedule

refers to only one Movie

and one Theater

. But everyone Theater

has a lot showings

and everyone Movie

has a lot screenings

. Using this model, a predicate matching your query would look like this:

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

      

+1


source







All Articles