2013-01-14 36 views

回答

2

可以计算总和前过滤销售。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"period == %@", @"2012-11"]; 
NSSet *sales = [self valueForKeyPath:@"sales"]; 
NSSet *filteredSales = [sales filteredSetUsingPredicate:predicate]; 
NSNumber *amount = [filteredSales valueForKeyPath:@"@sum.value"]; 

但是,当你有很多几十个或更多的销售,这种方法,因为它要求每个销售加载到内存中是不是真的有效。

而且,如果销售是过错的,各自出售将fire a fault并生成SQL请求。在过滤它们之前,您可以通过batch faulting阻止此销售。

我们将假设self是一个托管对象。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"period == %@", @"2012-11"]; 
NSSet *sales = [self valueForKeyPath:@"sales"]; 
// Begin batch-faulting 
NSManagedObjectContext *moc = [self managedObjectContext]; 
NSFetchRequest *request = [NSFetchRequest new]; 
[request setEntity:[NSEntityDescription entityForName:@"Sale" inManagedObjectContext:moc]]; 
[request setPredicate:[NSPredicate predicateWithFormat:@"self IN %@", sales]]; 
[request setReturnsObjectsAsFaults:NO]; 
[moc executeFetchRequest:request error:NULL]; 
// Batch-faulting done 
NSSet *filteredSales = [sales filteredSetUsingPredicate:predicate]; 
NSNumber *amount = [filteredSales valueForKeyPath:@"@sum.value"]; 

但是,你仍然可以为每个销售(被管理的对象,它的缓存,它的属性)数分配。最好的解决方案是使用提取请求来计算SQLite数据库中的总和。

NSString *reverseRelationship = @"store"; // name of the relationship from the sale to self 
NSExpressionDescription *description = [NSExpressionDescription new]; 
[description setName:@"amount"]; 
[description setExpressionResultType:NSDoubleAttributeType]; 
[description setExpression:[NSExpression expressionWithFormat:@"@sum.value"]]; 
NSManagedObjectContext *moc = [self managedObjectContext]; 
NSFetchRequest *request = [NSFetchRequest new]; 
[request setEntity:[NSEntityDescription entityForName:@"Sale" inManagedObjectContext:moc]]; 
[request setResultType:NSDictionaryResultType]; 
[request setPredicate:[NSPredicate predicateWithFormat: 
         @"%K == %@ AND period == %@", reverseRelationship, self, @"2012-11"]]; 
[request setPropertiesToFetch:@[description]]; 
NSDictionary *result = [[moc executeFetchRequest:request error:NULL] lastObject]; 
NSNumber *amount = [result objectForKey:@"amount"]; 
+0

不错的答案。最后一个解决方案中的“测试”可能是'self'? –

+0

它的工作原理!谢谢! – franciscomxs

+0

@MartinR是的,谢谢。我编辑了答案。 –