谓词适用于数组但不适用于fetchRequest

时间:2011-02-24 16:26:42

标签: objective-c ios nspredicate nsfetchrequest

我正在尝试创建一个fetchRequest,它向我展示了另一个数组中尚未存在的所有值。此代码返回我期望的数组:

NSArray *questionChoices = [self.currentQuestionChoiceGroup.questionChoices allObjects]; 
NSArray *filteredQuestionChoices  = [questionChoices filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NONE %@ == code", myarr]];

myarr包含1个项目,并且正如预期的那样,1个项目将从筛选结果中排除。但是,此代码不起作用:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"QuestionChoice" inManagedObjectContext:self.managedObjectContext];
request.predicate = [NSPredicate predicateWithFormat:@"NONE %@ == code AND questionChoiceGroup == %@", myarr, self.currentQuestionChoiceGroup];

当我执行此获取请求时,我获得属于当前questionChoiceGroup的所有questionChoices,包括具有myarr中的代码的那个。它似乎完全忽略了AND语句的第一部分。

我看不出两者之间会有什么不同,导致不同的结果。有人可以帮忙吗?

编辑更简单的解释:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"questionChoiceGroup == %@ AND NONE %@ == code", self.currentQuestionChoiceGroup, [NSArray arrayWithObject:@"A"]];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"displayOrder" ascending:YES]];
request.entity = [NSEntityDescription entityForName:@"QuestionChoice" inManagedObjectContext:self.managedObjectContext];

request.predicate = predicate;
NSArray *filteredQuestionChoices1 = [self.managedObjectContext executeFetchRequest:request error:nil];
NSLog(@"my filtered question choices 1: %@", [filteredQuestionChoices1 valueForKey:@"code"]);   

NSArray *filteredQuestionChoices2  = [filteredQuestionChoices1 filteredArrayUsingPredicate:predicate];
NSLog(@"my filtered question choices 2: %@", [filteredQuestionChoices2 valueForKey:@"code"]);

filteredQuestionChoices1包含代码为“A”的项目。 filteredQuestionChoices2没有该项目。第二个谓词如何过滤掉第一个谓词未过滤掉的内容?两个语句都使用完全相同的谓词。如果我在数组中使用谓词,如果完全相同的谓词将过滤掉那些对象,为什么我从fetchedRequest返回对象?

3 个答案:

答案 0 :(得分:4)

我会尝试重新修改你的谓词。而不是:

[NSPredicate predicateWithFormat:@"NONE %@ == code", myarr]

尝试:

[NSPredicate predicateWithFormat:@"NOT(code IN %@)", myarr]

我认为后者可能会更容易让CoreData转换为相应的SQL条件。

答案 1 :(得分:1)

在核心数据指南中查看Fetch Predicates and Sort Descriptors

如果您使用的是基于SQL的数据存储(例如,SQLite),则谓词将转换为SQL并由数据库调用,而不是由Cocoa调用。因此,您可以获得与标准数组相比不同的行为,并且对所支持的内容也有约束。具体而言,ALLANYIN操作有限制(您的NONE运算符相当于NOT( ANY ... ))。

看起来你正在尝试针对你作为参数提供的数组执行NONE操作,而不是从数据库中提取的数据数组。我愿意打赌这就是SQL翻译的谓词磕磕绊的地方。

答案 2 :(得分:0)

如果使用AND的语句有两个部分,请将每个部分括在括号中。此外,在与动态属性名称进行比较时,%K是适当的格式说明符。

request.predicate = [NSPredicate predicateWithFormat:@"(NONE %K == code) AND (questionChoiceGroup == %@"), myarr, self.currentQuestionChoiceGroup];

Apple的谓词编程指南中的一个例子:

  

Cocoa支持多种类型   谓词,包括以下内容:

     
      
  • 简单比较,例如成绩== 7   或firstName喜欢'Mark'

  •   
  • 案例或   变音符号不敏感的查找,例如   名称包含[cd]'citroen'

  •   
  • <强>逻辑   操作,例如(firstName   以“M”开头AND(lastName喜欢   '阿德利')

  •