theDVUSone
theDVUSone

Reputation: 215

Core Data Queries

I am still trying to wrap my head around Core Data and am having trouble letting go of SQL. I know that they are not the same but I am finding it hard to recreate what I can do in SQL. I am hoping someone can help.

What I want to do is create a list of Clients and return a sum of their current bill. I have two entities:

Client

Billing

I have created a one-to-many relationship between the 2 entities and have my NSEntityDescription pointing to Client.

Now what I want to happen in SQL terms is this:

SELECT *, SUM(amount) as Total FROM Clients INNER JOIN Billing......"

Upvotes: 2

Views: 773

Answers (1)

Dan Shelly
Dan Shelly

Reputation: 6011

Can this be done with one Fetch Request or would I do 2 Requests and then merge them?

Yes it can be done with one request. see here

/*UNTESTED*/
- (NSNumber*) billingSumForClient:(NSManagedObjectID*)clientId
                           context:(NSManagedObjectContext*)context
{
    NSNumber* total = nil;
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Billing"];
    [request setResultType:NSDictionaryResultType];
    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"amount"];
    NSExpression *sumExpression = [NSExpression expressionForFunction:@"sum:"
                                                            arguments:[NSArray arrayWithObject:keyPathExpression]];
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    [expressionDescription setName:@"total"];
    [expressionDescription setExpression:sumExpression];
    [expressionDescription setExpressionResultType:NSDateAttributeType];
    [request setPredicate:[NSPredicate predicateWithFormat:@"client == %@",clientId]];
    [request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
    NSError *error = nil;
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (&error) {
        // Handle the error.
    } else {
        if ([objects count] > 0) {
            total = [[objects objectAtIndex:0] valueForKey:@"total"];
        }
    }
    return total;
}

Can I somehow use valueForKey:@"[email protected]"?

Yes. see here(@Daniel link)
This might be faster if all your billings are already faulted into your current context.

Upvotes: 1

Related Questions