2009-11-08 3 views
3

première fois que je poste à ce tour, alors s'il vous plaît garder avec moi si je ne suis pas toutes les règles correctement. Je suis en train d'écrire une application pour l'iPhone (OS 3.1) et j'essaie d'écrire du code qui me permet d'ajouter des décimales. J'ai une entité Core Data appelée SimpleItem avec un attribut amount. Voici le cas de test je l'ai écrit:Calcul de la somme pour les valeurs décimales via Core Data ne fonctionne pas correctement?

// Create and configure objects 
    SimpleItem *si1 = [self createSimpleItem:@"si1"]; 
    si1.amount = [NSDecimalNumber decimalNumberWithMantissa:1000 exponent:0 isNegative:NO]; 
    SimpleItem *si2 = [self createSimpleItem:@"s12"]; 
    si2.amount = [NSDecimalNumber decimalNumberWithMantissa:2000 exponent:0 isNegative:NO]; 
    // Need to save prior to fetching results with NSDictionaryResultType (known limitation) 
    [self save]; 

    // Describe fetch request 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"SimpleItem" inManagedObjectContext:self.context]; 
    [request setEntity:entityDescription]; 
    [request setResultType:NSDictionaryResultType]; 

    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"amount"]; 
// For whatever reason, evaluating this expression here is absolutely not working. Probably decimals aren't handled properly. 
    NSExpression *sumAmountExpression = [NSExpression 
             expressionForFunction:@"max:" 
             arguments:[NSArray arrayWithObject:keyPathExpression]]; 

    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
    [expressionDescription setName:@"amount"]; 
    [expressionDescription setExpression:sumAmountExpression]; 
    [expressionDescription setExpressionResultType:NSDecimalAttributeType]; 
    [request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]]; 

    // Fetch the amounts 
    NSError *error = nil; 
    NSArray *array = [self.context executeFetchRequest:request error:&error]; 

Si j'exécute ce code par otest et le débogage, je reçois une exception lorsque la demande d'extraction est exécutée: « - [NSDecimalNumber compte]: sélecteur non reconnu envoyé à l'instance. " Cependant, l'évaluation de la fonction keyPathExpression sans la fonction d'agrégat fonctionne correctement.

Le reference documentation montre exactement le même exemple, donc je me demande ce que je fais mal. Ou cela pourrait-il être juste un bug?

Tous les meilleurs, Harald

+2

J'ai rencontré cela aussi; pense que c'est un bug dans les données de base car cela fonctionne dans le magasin SQL, mais pas dans la mémoire. Je vais déposer ceci dans le radar quand j'ai une chance. –

Répondre

0

Je pense que j'ai eu ce problème auparavant. IIRC, le problème est que vous avez défini votre type de résultat de recherche à NSDictionaryResultType mais vous le recevez dans un NSArray. Essayez de basculer le type de résultat d'extraction sur NSManagedObjectResultType qui retourne un tableau. Tous les exemples dans les documents utilisent la valeur par défaut NSManagedObjectResultType.

Dans tous les cas, le message d'erreur résulte clairement d'un objet NSDecimal envoyé message count d'un tableau. Vous pouvez le confirmer en piégeant le résultat dans un id. par exemple:

+0

Lors de la spécification d'un 'NSDictionaryResultType' vous recevrez un tableau contenant un objet via 'executeFetchRequest: error:'. –

+0

C'est ce que j'ai pour l'ailer de ma mémoire. – TechZen

0

Merci de m'avoir informé. Le fait est que je ne veux pas utiliser d'objets gérés. Après tout, je suis intéressé par les montants seulement et c'est ce que je reçois avec le dictionnaire. En outre, essayer d'étudier le problème tel que décrit ne fonctionnait pas car l'exécution de la requête de récupération échoue immédiatement et je ne récupère rien.

D'autres idées? Y a-t-il une autre possibilité d'obtenir des valeurs agrégées? Des "meilleures pratiques"? Au moment où je fais ce qui suit (suite du code ci-dessus):

NSExpressionDescription * expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName: @ "amount"]; [expressionDescription setExpression: keyPathExpression]; [expressionDescription setExpressionResultType: NSDecimalAttributeType]; [request setPropertiesToFetch: [NSArray arrayWithObject: expressionDescription]];

// Fetch the amounts 
NSError *error = nil; 
NSArray *array = [self.context executeFetchRequest:request error:&error]; 
if (array == nil) { 
    STFail(@"Fetch request could not be completed: %@", [error localizedDescription]); 
} 
STAssertEquals([array count], (NSUInteger) 2, @"Number of fetched objects != 2"); 

// Manually calculate the sum 
NSDecimalNumber *sum = nil; 
for (NSDictionary * dictionary in array) { 
    NSDecimalNumber *amount = (NSDecimalNumber *) [dictionary valueForKey:@"amount"]; 
    if (!sum) { 
     sum = amount; 
    } else { 
     sum = [sum decimalNumberByAdding:amount]; 
    } 
} 
STAssertNotNil(sum, @"Sum is nil"); 
STAssertTrue([sum isEqualToNumber:[NSDecimalNumber decimalNumberWithMantissa:3000 exponent:0 isNegative:NO]], 
       @"Sum != 3000: %@", sum); 

Cordialement, Harald

+0

Hey Harald, s'il vous plaît ne postez pas vos réponses comme une réponse à votre question. Au lieu de cela, vous devez utiliser la fonction "ajouter un commentaire" pour répondre directement aux réponses/commentaires et modifier votre question avec des informations supplémentaires telles que vous les trouvez. –

+0

Vous avez besoin d'une certaine quantité de réputation pour commenter, mettre à jour la question originale est bien cependant ... il suffit d'ajouter une nouvelle section avec l'information mise à jour afin que vous puissiez toujours voir la question originale – monowerker

0

Copie source donnée à un nouveau projet d'iPhone et en cours d'exécution que dans le simulateur a bien fonctionné ici. Je compilais contre le SDK 3.1.2 sur Snow Leopard.

C'est ce que j'ai utilisé pour le modèle de données:

model description http://homepage.mac.com/aclark78/.Public/Pictures/test%20model.png

Il doit y avoir quelque chose d'autre sur la cause de votre problème. Pouvez-vous décrire votre modèle ou le simplifier davantage?

+0

Voir mon commentaire à la question d'origine; Tu utilisais un magasin SQL? –

Questions connexes