0

I have a coredata project and I'm trying to make a query. Here is my coredata model:

enter image description here

NSManagedObjectContext *moc = [self managedObjectContext];
    NSEntityDescription *theaterDescription = [ NSEntityDescription entityForName:@"Theaters" inManagedObjectContext:moc];

     NSPredicate *theaterPredicate = [NSPredicate predicateWithFormat:@"nameOfTheater like %@ AND nameOfMovie like %@",_theaterName,_movieOutlet.stringValue];


    NSFetchRequest *theaterRequestTwo = [NSFetchRequest new];
    theaterRequestTwo.entity = theaterDescription;
    theaterRequestTwo.predicate = theaterPredicate;



    NSError *error = nil;

    NSArray *theaterResults = [moc executeFetchRequest:theaterRequestTwo error:&error];

But I'm getting this error:

keypath nameOfMovie not found in entity <NSSQLEntity Theaters id=3>

I also tried :

NSPredicate *theaterPredicate = [NSPredicate predicateWithFormat:@"nameOfTheater like %@ AND Movies.nameOfMovie like %@",_theaterName,_movieOutlet.stringValue];

But I got this error:

keypath Movies.nameOfMovie not found in entity <NSSQLEntity Theaters id=3>

And I also tried:

NSPredicate *theaterPredicate = [NSPredicate predicateWithFormat:@"nameOfTheater like %@ AND movies.nameOfMovie like %@",_theaterName,_movieOutlet.stringValue];

I got the following error:

to-many key not allowed here

By any chance any of you knows what I'm doing wrong or what I'm missing on my code. I'll really appreciate your help.

UPDATE:

This are the headers files for my coredata model:

theaters classe:

@class Movies;

@interface Theaters : NSManagedObject

@property (nonatomic, retain) NSString * nameOfTheater;
@property (nonatomic, retain) NSSet *movies;
@end

@interface Theaters (CoreDataGeneratedAccessors)

- (void)addMoviesObject:(Movies *)value;
- (void)removeMoviesObject:(Movies *)value;
- (void)addMovies:(NSSet *)values;
- (void)removeMovies:(NSSet *)values;

Movies class:

@class Schedules, Theaters;

@interface Movies : NSManagedObject

@property (nonatomic, retain) NSString * nameOfMovie;
@property (nonatomic, retain) NSSet *showTimes;
@property (nonatomic, retain) Theaters *theaters;
@end

@interface Movies (CoreDataGeneratedAccessors)

- (void)addShowTimesObject:(Schedules *)value;
- (void)removeShowTimesObject:(Schedules *)value;
- (void)addShowTimes:(NSSet *)values;
- (void)removeShowTimes:(NSSet *)values;

Schedules class:

@interface Schedules : NSManagedObject

@property (nonatomic, retain) NSDate * showTimes;
@property (nonatomic, retain) NSSet *movie;
@end

@interface Schedules (CoreDataGeneratedAccessors)

- (void)addMovieObject:(Movies *)value;
- (void)removeMovieObject:(Movies *)value;
- (void)addMovie:(NSSet *)values;
- (void)removeMovie:(NSSet *)values;
user2924482
  • 8,380
  • 23
  • 89
  • 173
  • The last solution seems to be the good hint to follow. Your issue is explained there: http://stackoverflow.com/questions/4217849/core-data-nspredicate-for-many-to-many-relationship-to-many-key-not-allowed – Larme Feb 10 '15 at 16:38

1 Answers1

4

you can use SUBQUERY for this kind of problems

one exact theater entity (copied by your example)

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"nameOfTheater like %@ AND SUBQUERY(movies, $mv, $mv.nameOfMovie like %@).@count > 0", _theaterName,_movieOutlet.stringValue];

UPDATE

all theaters where movie abc is running

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(movies, $mv, $mv.nameOfMovie CONTAINS[c] %@).@count > 0", @"abc"];

btw, is you model correct?

Theaters <->> Movies = 1:n

So every Theater has x Movies, but a Movie is running in only one Theater So if you fetch a Movie with name "abc" you can get the Theater as attibute. Or is it

Theaters <<->> Movies = n:m

? so movies and movieTheaters are NSSet<Movie>/NSSet<Theater>

UPDATE 2

still need an answer for the question above. what is the correct relation between? is one movie in x theaters or only in one. how are your header files for the ManagedObject classes? ;)

NSEntityDescription *schedulesDescription = [NSEntityDescription entityForName:@"Schedules" inManagedObjectContext:moc];

// something like this if 1:n. Try and post logs, have no IDE at the moment
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"movie.nameOfMovie == %@ AND movie.movieTheaters.nameOfTheater == %@", @"movie8", @"theaterOne"];

// if n:m, as far as I remember you couldn't fetch over 2 n:m relations via .
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"movie.nameOfMovie == %@ AND SUBQUERY(movie, $mv, $mv.movieTheaters.nameOfTheater == %@).@count > 0", @"movie8", @"theaterOne"];
geo
  • 1,781
  • 1
  • 18
  • 30
  • thank you for answer but I'm looking for the exact match. For example I have theaterOne showing Movie4. With the query you give I get the theater name and also the array of movies. Do you know how can I build the query just get the name of theater matching movie? – user2924482 Feb 10 '15 at 20:09
  • I can do everything xP but please explain more, I cannot follow you ^^ Do you want one theater entity or an array of all theaters where the movie is running? ^^ if second, I will update my answer – geo Feb 10 '15 at 20:22
  • each theater has movies and when and I need to query the name of the theater and movie to get all details of that pair. For example if theater named "theaterOne" is showing movie named "movie8" and I query for that NSPredicate *predicate = [NSPredicate predicateWithFormat:@"nameOfTheater like %@ AND SUBQUERY(movies, $mv, $mv.nameOfMovie like %@).@count > 0", @"theaterOne",@"movie8"]; <-- but in this case the result array I get all the movies showing in theaterOne. – user2924482 Feb 10 '15 at 20:39
  • you will always get the type of entity that is defined in the `NSEntityDescription`. So if you want to fetch `Movies` you have to change the description and the predicate. I update my answer so you can see how a fetch for schedules could look like – geo Feb 10 '15 at 21:25