1

我正在尝试创建一个 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"]);

filtersQuestionChoices1 包含一个代码为“A”的项目。filtersQuestionChoices2 没有该项目。第二个谓词如何过滤掉第一个谓词没有过滤掉的任何东西?两个语句都使用完全相同的谓词。如果我在数组上使用谓词,如果完全相同的谓词将过滤掉这些对象,为什么我要从 fetchedRequest 中取回对象?

4

3 回答 3

4

我会尝试修改你的谓词。代替:

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

尝试:

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

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

于 2011-03-04T19:10:12.430 回答
1

查看核心数据指南中的Fetch Predicates 和 Sort Descriptors

如果您使用的是基于 SQL 的数据存储(例如 SQLite),那么谓词将被转换为 SQL 并由数据库调用,而不是由 Cocoa 调用。因此,您可以获得与标准数组不同的行为,并且对支持的内容也有限制。ALL具体来说,对、ANY和操作有限制IN(您的NONE操作符相当于NOT( ANY ... ))。

看起来您正在尝试对NONE作为参数提供的数组执行操作,而不是从数据库中提取的数据数组。我敢打赌,这就是 SQL 翻译的谓词出现问题的地方。

于 2011-03-05T05:34:33.320 回答
0

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

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

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

Cocoa 支持多种类型的谓词,包括:

  • 简单的比较,例如 Grade == 7 或 firstName like 'Mark'

  • 不区分大小写或变音符号的查找,例如 name contains[cd] 'citroen'

  • 逻辑运算,例如 (firstName beginwith 'M') AND (lastName like 'Adderley')

于 2011-03-01T22:16:12.173 回答