核心数据谓词:谓词的未实现SQL生成

Tic*_*cko 13 iphone core-data objective-c ios

基本上我在我的数据模型中有3个实体:Brand,Model和Trim.

  • 品牌与模型之间存在一对多关系,称为"模型".(一个品牌有多个型号,但型号只有一个品牌)
  • 模型与Trim具有多对多关系,称为"修剪".(模型可以有多个修剪,修剪可以有多个模型)

拥有一系列修剪对象,我想让所有品牌都拥有一个"包含"此阵列中至少包含一个修剪的模型.

所以这是我的获取请求的谓词:

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Brand"];    
[NSPredicate predicateWithFormat:@"ANY models.trims IN %@", arrayOfTrims];
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (ANY models.trims IN {<Trim: 0x8e60340> (entity: Trim; id: 0x8e62f10 <x-coredata://BCD28560-AED5-4409-9A35-1925001773E6/Trim/p8>
Run Code Online (Sandbox Code Playgroud)

我是Core Data的新手,我不知道我做错了什么.

希望有人能提供帮助,

非常感谢.

Mar*_*n R 28

Core Data谓词中的"ANY"仅适用于单个到多个关系.由于您的查询涉及对多关系,因此您必须使用SUBQUERY:

[NSPredicate predicateWithFormat:@"SUBQUERY(models, $m, ANY $m.trims IN %@).@count > 0",
    arrayOfTrims];
Run Code Online (Sandbox Code Playgroud)

  • @MartinR,我通常访问stackoverflow假设我会找到答案.考虑到这个特殊问题,由于CoreData谓词在过去的成功有限,我的期望值最低.在这样的背景下,我很震惊地看到你的解决方案解决了我的问题.感谢您抽出宝贵时间发布它. (3认同)

Mar*_*kus 11

如果其中一个谓词使用不存在的列(即字段)名称,也会引发此异常.完全误导性的错误信息......


Dav*_*rry 5

在CoreData操作中使用谓词时,该谓词将转换为SQL。并非所有NSPredicate操作都无法进行这种转换,而您遇到的并非如此。我的建议是:

NSMutableArray* predicates = [NSMutableArray new];
for(NSString* trim in arrayOfTrims)
{
    [predicates addObject:[NSPredicate predicateWithFormat:@"%@ IN models.trims", trim]];
}
NSPredicate*    predicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];
Run Code Online (Sandbox Code Playgroud)


Mar*_*rra 5

IN可以使用该关键字,但不能同时应用ANY,因为在将其转换为SQL时这没有意义。

您最有可能寻找的谓词是:

[NSPredicate predicateWithFormat:@"models.trims IN %@", arrayOfTrims];
Run Code Online (Sandbox Code Playgroud)

但这在这种情况下也不起作用,因为您正在经历一段恋爱关系。因此,您需要做的是颠倒整个过程:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Model"];
[request setPredicate:[NSPredicate predicateWithFormat:@"trims in %@", arrayOfTrims]];

NSError *error = nil;
NSArray *modelArray = [moc executeFetchRequest:request error:&error];
if (!modelArray) {
  NSLog(@"Error: %@\n%@", [error localizedDescription], [error userInfo]);
}
NSArray parentObjectArray = [modelArray valueForKey:@"${PARENT_RELATIONSHIP_NAME}"];
Run Code Online (Sandbox Code Playgroud)

基本上,您要获取子对象以满足您的需求ANY,然后使用KVC来检索您关心的父对象。