2013-02-11 53 views
5

使用核心數據時,我遇到了一個問題。我有一個具有「金額」屬性的實體「運動」。我如何製作所有實例的「金額」的總和?我想了解如何使用NSExpressionDescription,但它足夠好NSSet。核心數據所有實例的總和屬性

回答

20

有一個managedObjectContext:

NSManagedObjectContext *managedObjectContext = ... 

我們創建返回類型的字典爲獲取請求:

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

然後我們創建一個表達式描述來計算的總和:

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

設置請求屬性以獲取:

fetchRequest.propertiesToFetch = @[expressionDescription]; 

如果需要,我們也可以設置謂詞。

最後我們執行請求並獲取一個包含帶有一個鍵(@「sumOfAmounts」)的字典的數組,它的值是一個具有金額總和的NSNumber。

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

乾杯

+1

爲什麼downvote? – e1985 2013-02-12 08:21:53

+0

對不起,這是我的不好,我想upvote ... Plz提供您的文章上的一個小編輯,所以我可以切換我的投票 – Yaman 2013-02-12 08:33:29

+0

謝謝你!效果很好! – Vins 2013-02-12 09:15:15

1

下面是使用NSExpressionNSExpressionDescription總結被管理對象的屬性的斯威夫特例子。該示例假定被管理對象被命名爲Movement並且總和屬性爲amount

實施例:

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 
} 

步驟的另外的討論:

步驟1 - 創建NSExpressionDescription變量。這個NSExpressionDescription指示對參數應用什麼類型的函數。 總和功能正在應用於數量屬性。

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

注意,參數參數是一個陣列。您可以在數組中傳遞不同類型的表達式,但在我們的情況下,我們只需要amount屬性。

步驟2 - 在此處建立獲取請求。請注意,結果類型被指定爲字典:fetchRequest.resultType = NSAttributeType.DictionaryResultType。在步驟3中,我們將使用的expression.name值作爲訪問總和值的關鍵。

第3步 - 我們執行獲取請求並返回將是一個元素數組。該元素將是我們種類爲[String:Double]let resultMap = results[0] as! [String:Double]的字典。該字典的值是Double,因爲在步驟1中我們指出expression.expressionResultType將是Double。

最後,我們通過調用與amountTotal鍵關聯的字典訪問值的總和:resultMap["amountTotal"]!


參考文獻:

NSExpressionNSExpressionDescription