我正在尝试创建一个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返回对象?
答案 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调用。因此,您可以获得与标准数组相比不同的行为,并且对所支持的内容也有约束。具体而言,ALL
,ANY
和IN
操作有限制(您的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喜欢 '阿德利')强>