2013-02-11 14 views
5

Mit Core-Daten stieß ich auf ein Problem. Ich habe eine Entität "Bewegung" mit einem Attribut "Betrag". Wie mache ich die Summe aller "Menge" aller Instanzen? Ich würde gerne verstehen, wie man NSExpressionDescription verwendet, aber es ist gut genug NSSet.Core-Daten Summe aller Instanzen Attribut

Antwort

20

Mit einem managedObjectContext:

NSManagedObjectContext *managedObjectContext = ... 

Wir schaffen eine Abrufanforderung mit Rückgabetyp Wörterbuch:

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Movement class])]; 
fetchRequest.resultType = NSDictionaryResultType; 

Dann erstellen wir einen Ausdruck Beschreibung die Summe zu berechnen:

NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
expressionDescription.name = @"sumOfAmounts"; 
expressionDescription.expression = [NSExpression expressionForKeyPath:@"@sum.amount"]; 
expressionDescription.expressionResultType = NSDecimalAttributeType; 

Legen Sie die Abrufeigenschaften fest:

fetchRequest.propertiesToFetch = @[expressionDescription]; 

Wir könnten auch ein Prädikat setzen, wenn wir wollen.

Zuletzt führen wir die Anfrage aus und erhalten ein Array mit einem Wörterbuch mit einem Schlüssel (@ "sumOfAmounts") und der Wert ist eine NSNummer mit der Summe der Beträge.

NSError *error = nil; 
NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
if (result == nil) 
{ 
    NSLog(@"Error: %@", error); 
} 
else 
{ 
    NSNumber *sumOfAmounts = [[result objectAtIndex:0] objectForKey:@"sumOfAmounts"]; 
} 

Prost

+1

Warum die downvote? – e1985

+0

Sorry, das ist mein schlecht, ich wollte ein wenig bearbeiten zu Ihrem Beitrag upvote ... Plz bieten, so kann ich meine Stimme – Yaman

+0

Dank Mann wechseln! funktioniert gut! – Vins

2

Der beste Weg ist es, eine fetch for specific values zu verwenden und eine NSExpressionDescription with a sum: function.

liefern Wenn Sie die Sie enthält ein Wörterbuch, dessen Schlüssel entsprechen die Ergebnisse der Ausdrücke sind die Expressionsbeschreibungen und deren Werte erhalten eine ein Element Array holen auszuführen. In diesem Fall erhalten Sie einen Schlüssel sum, dessen Wert die Summe der Attribute des Ausdrucks wäre.

1

Hier ist ein Swift Beispiel für die Verwendung NSExpression und NSExpressionDescription eines verwalteten Objekts Attribut summiert werden. In diesem Beispiel wird davon ausgegangen, dass das verwaltete Objekt den Namen Movement hat und das zu summierende Attribut amount ist.

Beispiel:

func sumAmount -> Double { 

    var amountTotal : Double = 0 

    // Step 1: 
    // - Create the summing expression on the amount attribute. 
    // - Name the expression result as 'amountTotal'. 
    // - Assign the expression result data type as a Double. 

    let expression = NSExpressionDescription() 
    expression.expression = NSExpression(forFunction: "sum:", arguments:[NSExpression(forKeyPath: "amount")]) 
    expression.name = "amountTotal"; 
    expression.expressionResultType = NSAttributeType.DoubleAttributeType 

    // Step 2: 
    // - Create the fetch request for the Movement entity. 
    // - Indicate that the fetched properties are those that were 
    // described in `expression`. 
    // - Indicate that the result type is a dictionary. 

    let fetchRequest = NSFetchRequest(entityName: "Movement") 
    fetchRequest.propertiesToFetch = [expression] 
    fetchRequest.resultType = NSAttributeType.DictionaryResultType 

    // Step 3: 
    // - Execute the fetch request which returns an array. 
    // - There will only be one result. Get the first array 
    // element and assign to 'resultMap'. 
    // - The summed amount value is in the dictionary as 
    // 'amountTotal'. This will be summed value. 

    do { 
     let results = try context.executeFetchRequest(fetchRequest) 
     let resultMap = results[0] as! [String:Double] 
     amountTotal = resultMap["amountTotal"]! 
    } catch let error as NSError { 
     NSLog("Error when summing amounts: \(error.localizedDescription)") 
    } 

    return amountTotal 
} 

Zusätzliche Diskussion der Schritte:

Schritt 1 - Erstellen Sie eine NSExpressionDescription Variable. Diese NSExpressionDescription gibt an, welche Art von Funktion auf die Argumente angewendet wird. Die Summe Funktion wird auf das Betrag Attribut angewendet.

expression.expression = NSExpression(forFunction: "sum:", 
    arguments:[NSExpression(forKeyPath: "amount")]) 

bemerken, dass die Argumente Parameter ist ein Array . Sie können verschiedene Arten von Ausdrücken im Array übergeben, aber in unserem Fall wollen wir nur das Attribut amount.

Schritt 2 - Die Abrufanforderung wird hier festgelegt. Beachten Sie, dass der Ergebnistyp als Wörterbuch angegeben ist: fetchRequest.resultType = NSAttributeType.DictionaryResultType. In Schritt 3 verwenden wir den Wert expression.name von amountTotal als Schlüssel für den Zugriff auf den summierten Wert.

Schritt 3 - Wir führen die Abrufanforderung aus und geben ein Ein-Element-Array zurück. Das Element wird ein Wörterbuch sein, das wir zu [String:Double]: let resultMap = results[0] as! [String:Double] haben. Der Wert des Wörterbuchs ist ein Double, weil in Schritt 1 angegeben wurde, dass expression.expressionResultType ein Double wäre.

Schließlich greifen wir auf die Summe durch den Wörterbuchwert mit dem amountTotal Schlüssel zugeordnet Aufruf: resultMap["amountTotal"]!


Referenzen:

NSExpression und NSExpressionDescription

Verwandte Themen