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

时间:2014-02-28 16:56:43

标签: ios iphone objective-c core-data

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

  • 一个品牌与Model有一对多的关系称为" models"。 (一个品牌有多个型号,但型号只有一个品牌)
  • 模型与Trim有多对多的关系称为" trims"。 (模型可以有多个修剪,修剪可以有多个模型)

拥有一系列修剪对象,我想让所有品牌都拥有一个"包含"此数组中至少包含一个修剪。

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

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Brand"];    
[NSPredicate predicateWithFormat:@"ANY models.trims IN %@", arrayOfTrims];

这是我得到的错误:

*** 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>

我对核心数据有点新意,我不知道我做错了什么。

希望有人能提供帮助,

非常感谢。

5 个答案:

答案 0 :(得分:28)

核心数据谓词中的“任何”仅适用于单个到多个关系。 由于您的查询涉及两个到多个关系,因此您必须使用SUBQUERY:

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

答案 1 :(得分:10)

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

答案 2 :(得分: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];

答案 3 :(得分:5)

可以使用关键字IN,但是当您将其转换为SQL时,您无法同时应用任何ANY。

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

[NSPredicate predicateWithFormat:@"models.trims IN %@", arrayOfTrims];

但是在这种情况下,这不会起作用,因为你正在经历一段关系。所以你需要做的就是扭转整个事情:

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}"];

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

答案 4 :(得分:0)

在我的情况下,出现此错误是因为我犯了一个愚蠢的错误,并且没有在正确的数据类型中使用参数。

我正在尝试做:

let firstPredicate = NSPredicate(format: "firstName BEGINSWITH[cd] %@", firstNameField.stringValue)

而忘记放置“ .stringValue”。