Effectuer la multiplication (agrégation) avec CoreData: comment?

Suite à un fantastique tutoriel de Jeff Lamarche , j'essaie d'agréger des données pour une sous-class spécifique de NSManagedObject .

C'est le scénario. J'ai créé une class nommée Product qui étend la class NSManagedObject . Product class de Product a trois propriétés comme:

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

J'ai également créé une catégorie, appelée Product+Aggregate , dans laquelle j'effectue une agrégation de sum. En particulier, suivant le tutoriel de Jeff, j'ai géré l'atsortingbut sum for quantity.

 +(NSNumber *)aggregateOperation:(NSSsortingng *)function onAtsortingbute:(NSSsortingng *)atsortingbuteName withPredicate:(NSPredicate *)predicate inManagedObjectContext:(NSManagedObjectContext *)context { NSSsortingng* className = NSSsortingngFromClass([self class]); NSExpression *ex = [NSExpression expressionForFunction:function arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:atsortingbuteName]]]; NSExpressionDescription *ed = [[NSExpressionDescription alloc] init]; [ed setName:@"result"]; [ed setExpression:ex]; [ed setExpressionResultType:NSInteger64AtsortingbuteType]; 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; } 

Cette méthode de class est appelée comme suit à partir d'un UIViewController spécifique:

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

Le code fonctionne bien. En fait, si j'ai dit 3 produits

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

La méthode aggregateOperation renvoie 7 comme prévu.

Maintenant, j'aurais un pas de plus. En modifiant cette méthode, je dois returnner le coût total pour la command du produit. En d'autres termes, j'ai besoin de calculer la valeur de QUANTITÉ * PRIX pour chaque produit et finalement returnner le TOTAL.

Pourrais-tu me suggérer le bon path? Merci d'avance.

EDIT C'est le nouveau code que j'utilise après la suggestion de Cyberfox mais malheureusement ça ne marche pas.

 NSSsortingng* className = NSSsortingngFromClass([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:NSInteger64AtsortingbuteType]; // same as before 

Pour ceux qui s'intéressent à, j'ai trouvé la solution au problème ci-dessus.

Voici le code:

 static NSSsortingng* exprName1 = @"val1"; static NSSsortingng* exprName2 = @"val2"; NSSsortingng *className = NSSsortingngFromClass([self class]); NSExpression *quantityPathExpression = [NSExpression expressionForKeyPath:firstAtsortingbute]; //eg quantity NSExpression *unitaryPricePathExpression = [NSExpression expressionForKeyPath:secondAtsortingbute]; //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 pour l'utiliser crée une méthode Class qui returnne un NSNumber et accepte comme parameters le context géré et 2 attributes ( NSSsortingng ) où vous voulez effectuer l'extraction de données.

J'espère que cela aide!

C'est un coup dans l'obscurité, parce que pour répliquer votre code je devrais build une database, etc., mais je crois que vous voulez:

 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 est un tableau de la paire d'expressions se référant à la quantity et au price . multiplyExpression est l'expression multiply:by: avec les parameters de quantityPrice . ex est votre sum: expression, référençant l'expression multiple référençant les paths keys quantité et prix.

Je suis sûr que vous voudriez faire quelque chose comme ça, mais je ne peux pas le tester sans un DB configuré comme le vôtre, etc., donc c'est juste de la théorie.