CoreData通过抽象托管对象获取请求到具体的托管对象

时间:2009-10-01 16:45:58

标签: sqlite core-data nspredicate

我正在尝试使用谓词执行针对托管对象上下文的获取请求,该谓词针对抽象类的某些子类中存在的键路径进行测试。

例如,这里是对象模型的一部分

Library::NSManagedObject
 - AllMovies::to-many relationship->Movie

Movie::NSManagedObject (abstract)
 - type::String
 - name::String
 - mylibrary::to-one relationship->Library

HorrorMovie::Movie
 - monster::String
 - ghosts::BOOL

RomanceMovie::Movie
 - percociouskid::String
 - hasferret::BOOL

如果我设置了以下提取请求

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Library" 
                                                     inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
                            @"(SUBQUERY(AllMovies, $movies, 
                                                   $movies.type like[c] 'horror' and
                                                   $movies.moster like[c] 'yeti'
                                       ).@count != 0)"
                          ] 
[request setPredicate:predicate];

NSArray *array = [moc executeFetchRequest:request error:&error];

执行获取请求会返回错误,如

keypath $movies.monster not found in entity <NSSQLEntity Movie id=2>

似乎没有办法对谓词进行延迟评估。我已经尝试过的其他一些东西是一个ANY谓词,使用CAST关键字,试图用另一个SUBQUERY替换SUBQUERY中的'AllMovies'以返回一组与'type'值匹配的对象。

可以为每种合格类型做多个请求,但这是粗略,缓慢和笨拙的。

这是在OS X 10.6下使用SQL持久性存储。做一个内存商店不是一个选择,因为我正在使用100万+'Libraries'(该项目与电影没有任何关系,但我认为这是一个很好的例子)。

谢谢, 罗布

1 个答案:

答案 0 :(得分:1)

这不起作用,因为您的实体模型只是告诉Core Data AllMovies关系包含Movie个对象。因此,Core Data希望只能发送Movie对象理解的那些消息。当它发起fetch时,它会针对每个Movie对象(由获取实体指定)测试谓词。

但是,Movie实体和RomanceMovie实体都不了解monster消息(因为它们缺少属性。)谓词测试是无意义的。这就是你得到错误的原因。

您需要重新考虑您的设计。使用实体继承可能不是你想要的方式。