用CoreData执行乘法(聚合):如何?

在Jeff Lamarche的一个奇妙的教程之后,我试图为NSManagedObject的特定子类聚合数据。

这是情况。 我创build了一个名为Product的类来扩展NSManagedObject类。 Product类有三个属性,如下所示:

 @property (nonatomic, retain) NSString* name; @property (nonatomic, retain) NSNumber* quantity; @property (nonatomic, retain) NSNumber* price; 

我也创build了一个名为Product+Aggregate的类别,在这里我执行一个总和聚合。 特别是在Jeff教程之后,我pipe理了数量属性的总和。

 +(NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inManagedObjectContext:(NSManagedObjectContext *)context { NSString* className = NSStringFromClass([self class]); NSExpression *ex = [NSExpression expressionForFunction:function arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]]; NSExpressionDescription *ed = [[NSExpressionDescription alloc] init]; [ed setName:@"result"]; [ed setExpression:ex]; [ed setExpressionResultType:NSInteger64AttributeType]; NSArray *properties = [NSArray arrayWithObject:ed]; [ed release]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setPropertiesToFetch:properties]; [request setResultType:NSDictionaryResultType]; if (predicate != nil) [request setPredicate:predicate]; NSEntityDescription *entity = [NSEntityDescription entityForName:className inManagedObjectContext:context]; [request setEntity:entity]; NSArray *results = [context executeFetchRequest:request error:nil]; NSDictionary *resultsDictionary = [results objectAtIndex:0]; NSNumber *resultValue = [resultsDictionary objectForKey:@"result"]; return resultValue; } 

这个类的方法在特定的UIViewController被调用如下:

 NSNumber *totalQuantity = [Product aggregateOperation:@"sum:" onAttribute:@"quantity" withPredicate:nil inManagedObjectContext:self.context]; 

代码运行良好。 事实上,如果我说3产品

 NAME QUANTITY PRICE PRODUCT 1 2 23.00 PRODUCT 2 4 12.00 PRODUCT 3 1 2.00 

如预期的那样, aggregateOperation方法返回7。

现在我要多一步。 修改该方法,我需要返回产品订单的总成本。 换句话说,我需要计算每个产品的QUANTITY * PRICE值,最后返回TOTAL。

你能build议我正确的方法吗? 先谢谢你。

编辑这是Cyber​​foxbuild议后使用的新代码,但不幸的是它不起作用。

 NSString* className = NSStringFromClass([self class]); NSArray *quantityPrice = [NSArray arrayWithObjects: [NSExpression expressionForKeyPath:@"quantity"], [NSExpression expressionForKeyPath:@"price"], nil]; NSArray *multiplyExpression = [NSArray arrayWithObject:[NSExpression expressionForFunction:@"multiply:by:" arguments:quantityPrice]]; NSExpression *ex = [NSExpression expressionForFunction:function arguments:multiplyExpression]; NSExpressionDescription *ed = [[NSExpressionDescription alloc] init]; [ed setName:@"result"]; [ed setExpression:ex]; [ed setExpressionResultType:NSInteger64AttributeType]; // same as before 

对于那些感兴趣的,我find了上述问题的解决scheme。

代码如下:

 static NSString* exprName1 = @"val1"; static NSString* exprName2 = @"val2"; NSString *className = NSStringFromClass([self class]); NSExpression *quantityPathExpression = [NSExpression expressionForKeyPath:firstAttribute]; //eg quantity NSExpression *unitaryPricePathExpression = [NSExpression expressionForKeyPath:secondAttribute]; //eg price NSExpressionDescription *quantityED = [[NSExpressionDescription alloc] init]; [quantityED setName:exprName1]; [quantityED setExpression:quantityPathExpression]; [quantityED setExpressionResultType:NSDictionaryResultType]; NSExpressionDescription *unitaryPriceED = [[NSExpressionDescription alloc] init]; [unitaryPriceED setName:exprName2]; [unitaryPriceED setExpression:unitaryPricePathExpression]; [unitaryPriceED setExpressionResultType:NSDictionaryResultType]; NSArray *properties = [NSArray arrayWithObjects:quantityED, unitaryPriceED, nil]; [quantityED release]; [unitaryPriceED release]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setPropertiesToFetch:properties]; [request setResultType:NSDictionaryResultType]; if (predicate != nil) [request setPredicate:predicate]; NSEntityDescription *entity = [NSEntityDescription entityForName:className inManagedObjectContext:context]; [request setEntity:entity]; NSError* error = nil; NSArray *results = [context executeFetchRequest:request error:&error]; if(error != nil) { NSLog(@"An error occurred: %@", [error localizedDescription]); abort(); } float total = 0; for (NSDictionary *resultDict in results) { NSNumber* quantityNumber = [resultDict valueForKey:exprName1]; NSNumber* unitaryPriceNumber = [resultDict valueForKey:exprName2]; int moltVal = [quantityNumber intValue]*[unitaryPriceNumber intValue]; total += moltVal; } return [NSNumber numberWithInt:total]; 

PS使用它创build一个类方法,返回一个NSNumber并接受作为参数的托pipe的上下文和2属性( NSString )你想执行数据检索。

希望能帮助到你!

这是在黑暗中的一个镜头,因为复制你的代码,我需要build立一个数据库等,但我相信你想要:

 NSArray *quantityPrice = [NSArray arrayWithObjects: [NSExpression expressionForKeyPath:@"quantity"], [NSExpression expressionForKeyPath:@"price"], nil]; NSArray *multiplyExpression = [NSArray arrayWithObject:[NSExpression expressionForFunction:@"multiply:by:" arguments:quantityPrice]]; NSExpression *ex = [NSExpression expressionForFunction:function arguments:multiplyExpression]; 

quantityPrice是一对表示quantityprice的expression式的数组。 multiplyExpression是expression式multiply:by:quantityPrice的参数。 ex是您的sum:expression式,引用引用数量和价格关键path的多重expression式。

我很肯定你会想做这样的事情,但是如果没有象你的那样build立一个数据库,我不能testing它,所以这只是理论。