CoreData: Using NSPredicate to filter one to many to many relationship (error to-many key not allowed here)
CoreData: Using NSPredicate to filter one to many to many relationship (error to-many key not allowed here)
我有 coreData 模型:
我正在尝试验证电影的时间表是否与电影和剧院相符,但出现错误 "to-many key not allowed here"
这是我的代码:
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *timeDescription = [ NSEntityDescription entityForName:@"Schedules" inManagedObjectContext:moc];
NSPredicate *timePredicate = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *moviePredicate = [NSPredicate predicateWithFormat:@"ANY movie.nameOfMovie CONTAINS[cd] %@", _movie];
NSPredicate *theatersPredicate = [NSPredicate predicateWithFormat:@"movie.theaters.nameOfTheater == %@", _theaterName];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[timePredicate,moviePredicate,theatersPredicate]];
NSFetchRequest *request = [NSFetchRequest new];
request.predicate = compoundPredicate;
request.entity = timeDescription;
NSError *error = nil;
NSArray *result = [moc executeFetchRequest:request error:&error];
如果我只使用以下谓词:
NSPredicate *timePredicate = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *moviePredicate = [NSPredicate predicateWithFormat:@"ANY movie.nameOfMovie CONTAINS[cd] %@", _movie];
我可以得到时间表和电影的匹配,但我的问题是我怎样才能得到时间表和电影和剧院的匹配你们知道我做错了什么吗?
非常感谢你的帮助
您收到 "to-many key not allowed here" 错误是因为,在您的 theatersPredicate
中,"movie" 是一对多关系。与您的 moviePredicate
比较,它工作正常,因为它使用 "ANY" 关键字。
因此,您可能只想将 "ANY" 添加到您的 theatersPredicate
。这会起作用(即编译和 运行 OK),但我认为不会给你你正在寻找的结果:它会显示那些“(任何电影的电影名称匹配)和(任何电影的 nameOfTheatre火柴)”。但在每种情况下都可能是不同的电影。
我想你想要的是"ANY movies where (moviename matches AND nameOfTheatre matches)"。为此,使用 SUBQUERY:
NSPredicate *timePredicate = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *movieAndTheaterPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(movie, $x, $x.nameOfMovie CONTAINS[cd] %@ AND $x.theaters.nameOfTheater == %@).@count > 0", _movie, _theaterName];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[timePredicate,movieAndTheaterPredicate]];
我有 coreData 模型:
我正在尝试验证电影的时间表是否与电影和剧院相符,但出现错误 "to-many key not allowed here"
这是我的代码:
NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *timeDescription = [ NSEntityDescription entityForName:@"Schedules" inManagedObjectContext:moc];
NSPredicate *timePredicate = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *moviePredicate = [NSPredicate predicateWithFormat:@"ANY movie.nameOfMovie CONTAINS[cd] %@", _movie];
NSPredicate *theatersPredicate = [NSPredicate predicateWithFormat:@"movie.theaters.nameOfTheater == %@", _theaterName];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[timePredicate,moviePredicate,theatersPredicate]];
NSFetchRequest *request = [NSFetchRequest new];
request.predicate = compoundPredicate;
request.entity = timeDescription;
NSError *error = nil;
NSArray *result = [moc executeFetchRequest:request error:&error];
如果我只使用以下谓词:
NSPredicate *timePredicate = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *moviePredicate = [NSPredicate predicateWithFormat:@"ANY movie.nameOfMovie CONTAINS[cd] %@", _movie];
我可以得到时间表和电影的匹配,但我的问题是我怎样才能得到时间表和电影和剧院的匹配你们知道我做错了什么吗?
非常感谢你的帮助
您收到 "to-many key not allowed here" 错误是因为,在您的 theatersPredicate
中,"movie" 是一对多关系。与您的 moviePredicate
比较,它工作正常,因为它使用 "ANY" 关键字。
因此,您可能只想将 "ANY" 添加到您的 theatersPredicate
。这会起作用(即编译和 运行 OK),但我认为不会给你你正在寻找的结果:它会显示那些“(任何电影的电影名称匹配)和(任何电影的 nameOfTheatre火柴)”。但在每种情况下都可能是不同的电影。
我想你想要的是"ANY movies where (moviename matches AND nameOfTheatre matches)"。为此,使用 SUBQUERY:
NSPredicate *timePredicate = [NSPredicate predicateWithFormat:@"showTimes <= %@", _movieTime];
NSPredicate *movieAndTheaterPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(movie, $x, $x.nameOfMovie CONTAINS[cd] %@ AND $x.theaters.nameOfTheater == %@).@count > 0", _movie, _theaterName];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[timePredicate,movieAndTheaterPredicate]];