用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议我正确的方法吗? 先谢谢你。
编辑这是Cyberfoxbuild议后使用的新代码,但不幸的是它不起作用。
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
是一对表示quantity
和price
的expression式的数组。 multiplyExpression
是expression式multiply:by:
与quantityPrice
的参数。 ex
是您的sum:
expression式,引用引用数量和价格关键path的多重expression式。
我很肯定你会想做这样的事情,但是如果没有象你的那样build立一个数据库,我不能testing它,所以这只是理论。