如何计入coredata(聚合)?
Posted
技术标签:
【中文标题】如何计入coredata(聚合)?【英文标题】:How to count in coredata (aggregation)? 【发布时间】:2010-07-27 10:09:46 【问题描述】:我正在学习核心数据,尤其是在聚合方面。
目前我想做的事情:计算表中的记录数,该表在某些条件下与反向关系存在一对多关系。
目前我正在这样做:
NSExpression *ex = [NSExpression expressionForFunction:@"count:"
arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"ddname"]]];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"ddtype == 'Home'"];
NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
[ed setName:@"countDDEvents"];
[ed setExpression:ex];
[ed setExpressionResultType:NSInteger16AttributeType];
NSArray *properties = [NSArray arrayWithObject:ed];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setPredicate:pred];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]];
[request setEntity:entity];
NSArray *results = [[self.currentAccount managedObjectContext] executeFetchRequest:request error:nil];
NSDictionary *dict = [results objectAtIndex:0];
NSLog(@"Average birthdate for female heroes: %@", [dict objectForKey:@"countDDEvents"]);
它来自 jeff lemarche。
EDIT:我发现我的解决方案是
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"ddtype == 'Home'"];
[request setPredicate:pred];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]];
[request setEntity:entity];
NSError *error = nil;
NSUInteger count = [[self.currentAccount managedObjectContext] countForFetchRequest:request error:&error];
它工作得很好。但我想一次做更多这种类型的请求。所以我认为这不是获得计数的首选方式。
编辑:
所以我认为这种方法是合适的????
那么任何人都可以告诉我更有效的首选方式吗?
谢谢。
【问题讨论】:
【参考方案1】:我必须计算大约 10 000 个实体,并且在使用 countForFetchRequest 时会大大降低我的界面响应速度。
这是一种使用 NSExpression 的方法:
- (NSUInteger) unfilteredFCsCount
// Just the fetchRequest
NSFetchRequest *fetchRequest = [self unfilteredFCsFetchRequest];
[fetchRequest setResultType: NSDictionaryResultType];
// You can use any attribute of the entity. its important, because you are not counting
// the properties, but actually the entities
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"sortIndex_"]; // Does not really matter
NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:"
arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: @"fcCount"];
[expressionDescription setExpression: maxExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];
[fetchRequest setPropertiesToFetch: [NSArray arrayWithObject:expressionDescription]];
NSUInteger fcCount = 0;
NSError *error = nil;
NSArray *results = nil;
results = [self.managedObjectContext executeFetchRequest: fetchRequest error: &error];
KSLog(KSLogLevelDebug, @"unfilteredFCsCount results: %@", results);
if([results count] > 0)
NSNumber *count = [[results objectAtIndex: 0] objectForKey: @"fcCount"];
fcCount = [count intValue];
return fcCount;
【讨论】:
【参考方案2】:Jeff LaMarche 只是用这个作为一个简单的例子。在实践中,这种需求非常普遍,以至于 Key-Value Coding 有一个内置宏来处理它和其他常见的收集操作。
见:The Key-Value Programming Guide: Set and Array Operators
在这种情况下,您将在谓词中使用@count
运算符。
当然,手动调整您自己的表达式可以让您更好地控制您的谓词,但运算符处理 80% 的此类任务。
【讨论】:
以上是关于如何计入coredata(聚合)?的主要内容,如果未能解决你的问题,请参考以下文章