NSFetchRequest 中函数计数的表达式返回比常规 fetch 少 1

Posted

技术标签:

【中文标题】NSFetchRequest 中函数计数的表达式返回比常规 fetch 少 1【英文标题】:Expression for function count in NSFetchRequest returns one less than regular fetch 【发布时间】:2010-12-09 15:46:03 【问题描述】:

在我第一次尝试在获取请求中使用 NSExpression 时,我得到的结果与我使用常规获取请求时得到的结果一致。

MO“Subject”与 MO“Book”有一对多的关系,相反的关系是一对一。

这是我正在使用的 NSExpression fetchRequest:

Project_AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@“Book”
                                                     inManagedObjectContext:context];
Subject *subjectToDelete = [self.arrayOfSubjects objectAtIndex:indexSelected];    
NSPredicate *pred = [NSPredicate predicateWithFormat:@"subject == %@", subjectToDelete];
NSExpression *expn = [NSExpression expressionForFunction:@"count:" 
                                                     arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"idPerm"]]];
NSExpressionDescription *expnDesc = [[NSExpressionDescription alloc] init];
[expnDesc setExpression:expn];
[expnDesc setName:@“countMatchingBooks”];
[expnDesc setExpressionResultType:NSInteger64AttributeType];
NSArray *properties = [NSArray arrayWithObject:expnDesc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription]; 
[request setPredicate:pred];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];
NSError *error = nil; 
NSArray *results = [context executeFetchRequest:request error:&error];
if (error) 
    // error handling here

[request release];
[expnDesc release];

// Retrieve the count from the results array.
NSNumber *numBooksAssignedSubjectToDelete = [[results objectAtIndex:0] valueForKey:@“countMatchingBooks”];
uint64_t uloloBooksAssignedSubjectToDelete = [numBooksAssignedSubjectToDelete unsignedLongLongValue];

(我们的想法是向用户提供一个确认面板,告知他们如果选择删除所选主题,将通过级联规则删除多少本书 - 此时不会出错。)

这是我用作测试的简单 fetchRequest:

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@“Book”
                                                     inManagedObjectContext:contextMain];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription]; 
NSError *error = nil; 
NSArray *booksAll = [contex executeFetchRequest:request error:&error];
[request release];
// Loop through the “booksAll” array and count those whose subject matches the one assigned as “subjectToDelete”

如果 NSExpression fetchRequest 返回计数为 n,那么简单的 fetchRequest 返回计数为 n + 1。

考虑到 fetchRequests 本身可能会以某种方式改变数据,我尝试以不同的顺序运行它们,但结果相同。

也许使用表达式的请求会跳过尚未保存的 MO?不会。我运行了一个测试,创建了一堆新的“Book” MO,以查看表达式请求和常规请求之间的差距是否会扩大。它仍然是一个关闭。

知道我做错了什么吗?

【问题讨论】:

【参考方案1】:

使用 NSExpressionDescription 的 NSFetchRequests 不包括未保存的对象。 NSFetchRequest 有一个方法 -setIncludePendingChanges:,当结果类型为 NSDictionaryResultType 时不接受 YES。这意味着您不能使用 NSExpressionDescription 来获取未保存的对象。

【讨论】:

感谢您的回复。但是你如何解释我在不保存上下文的情况下插入多个新 MO 时运行的测试结果,但使用 NSExpressionDescription 的结果仍然只有一次,如果你说的是真的,它应该已经关闭了这些新MO的全部数量?现在,可能是我犯了一些错误,并在获取之前以某种方式保存了上下文——我会仔细检查... 你是对的!我运行了表达式提取,然后在不保存上下文的情况下插入了 9 个新的 MO,然后再次运行了表达式提取。两次都得出相同的计数!自从最初的测试以来,该项目发生了很大变化,我无法确定我当时做错了什么,但我必须在插入单个新 MO 时包含一个保存上下文的调用。无论如何,我很高兴知道表达式提取是可靠的;我可以通过insertedObjects 循环补充。真的非常感谢;我已经放弃了。

以上是关于NSFetchRequest 中函数计数的表达式返回比常规 fetch 少 1的主要内容,如果未能解决你的问题,请参考以下文章

按对象 ID 对字典 NSFetchRequest 进行分组

NSFetchRequest 按月分组

用于 groupby 和 count 组合的 NSFetchRequest

如何使用 NSExpression 使用自定义函数设置 NSFetchRequest propertiesToFetch

在多列上迭代和应用正则表达式函数/str 计数

无法转换'NSFetchRequest类型的值 '到指定类型'NSFetchRequest “