Help with a CoreData request

I am looking for ways to write some basic queries in CoreData, and there are no examples in the documentation. Below is my request:

  • I have an Expense object and it has an accountAmount field.
  • An expense can be associated with an ExpenseCategory object.
  • An ExpenseCategory can simply define an expense category (e.g. Food) or it can have a unit (e.g. mileage). If this is just a name, the expense value is the cost counter in the Costs object, otherwise it is a expense. * UnitRate in ExpenseCategory.
  • Since the link "Cost per category" is optional, the final expense will be based on the presence / absence of the category and speed of the unit.

Thus, the SQL query to calculate the total costs will be as follows:

select
    TOTAL(e.amount * IFNULL(c.rate, 1))
from EXPENSE e
LEFT OUTER join CATEGORY c on
    e.category = c.id

How can this be done in CoreData?

+5
1

Expense, .

.

- (NSDecimalNumber *) calculatedExpenseAmount {

  NSDecimalNumber *actualAmount = self.expenseAmount;

  // Pseudo-code begins
  if (self.expenseCategory != nil) {
    actualAmount = self.expenseAmount * self.expenseCategory.unitRate;
  }

  return actualAmount;
}

.

, NSDictionary-result, costAmount costsCategory.unitRate.

- (NSDecimalNumber *) totalExpenses
{
    // Fetch all of the expense amounts and unit rate of any related category.

    NSFetchRequest *request = ...;
    [request setManagedObjectContext:<...>];
    [request setEntity:<ExpenseAccountDescription>];
    [request setResultType:NSDictionaryResultType];
    NSArray *props = [NSArray arrayWithObjects:@"expenseAmount", @"category.unitRate", nil];
    [request setPropertiesToFetch:props];

    NSArray *amounts = [request executeRequest:...];
    // amounts is an array of dictionaries, each hold the desired property values.

    // Loop and sum the individual amounts

    NSDecimal *total = [[NSDecimalNumber zero] decimalNumber];
    NSAutoreleasePool *pool = nil; // contain the mess

    NSCalculationError err = NSCalculationNoError;

    for (NSDictionary *result in amounts) 
    {
        pool = [NSAutoreleasePool new];

        NSDecimal newTotal = [[NSDecimalNumber zero] decimalNumber];
        NSDecimalNumber *expenseAmount = [result valueForKeyPath:@"expenseAmount"];
        NSDecimalNumber *unitRate = [result valueForKeyPath:@"category.unitRate"];

        if (unitRate != nil) {
            // do the unit rate multiplication and accumulate the result in the total

            NSDecimal calculated = [[NSDecimalNumber zero] decimalNumber];
            err = NSDecimalMultiply (&calculated, [expenseAmount decimalNumber], [unitRate decimalNumber], NSRoundBankers);
            if (err == NSCalculationNoError) {
                err = NSDecimalAdd (&newTotal, total, calculated, NSRoundBankers);
            }
        }
        else {
            // just accumulate the result in the total

            err = NSDecimalAdd (&newTotal, total, [expenseAmount decimalNumber], NSRoundBankers);
        }

        // Keep the new total
        NSDecimalCopy(&total, newTotal);

        [pool drain];
    }

    return [NSDecimalNumber decimalNumberWithDecimal:total];
}

10000 , 1 . , .

+2

All Articles