2010-07-27 18 views
6

Ich lerne Kerndaten und arbeite besonders an Aggregation.Wie in Coredata (Aggregation) zählen?

Aktuelle was ich tun möchte: zählen Sie die Anzahl der Datensätze aus der Tabelle, die in einigen Beziehungen mit umgekehrten Beziehung ist.

Zur Zeit mache ich das:

NSExpression *ex = [NSExpression expressionForFunction:@"count:" 
               arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"ddname"]]]; 
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"ddtype == 'Home'"]; 
    NSExpressionDescription *ed = [[NSExpressionDescription alloc] init]; 
    [ed setName:@"countDDEvents"]; 
    [ed setExpression:ex]; 
    [ed setExpressionResultType:NSInteger16AttributeType]; 
    NSArray *properties = [NSArray arrayWithObject:ed]; 
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    [request setPredicate:pred]; 
    [request setPropertiesToFetch:properties]; 
    [request setResultType:NSDictionaryResultType]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]]; 
    [request setEntity:entity]; 
    NSArray *results = [[self.currentAccount managedObjectContext] executeFetchRequest:request error:nil]; 
    NSDictionary *dict = [results objectAtIndex:0]; 
    NSLog(@"Average birthdate for female heroes: %@", [dict objectForKey:@"countDDEvents"]); 

Sein von jeff lemarche.

EDIT: und ich habe meine Lösung als

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"ddtype == 'Home'"]; 
    [request setPredicate:pred]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]]; 
    [request setEntity:entity]; 

    NSError *error = nil; 
    NSUInteger count = [[self.currentAccount managedObjectContext] countForFetchRequest:request error:&error]; 

Es funktioniert gut gefunden .Aber ich mehr Anfrage dieser Art zu einer Zeit tun wollen. Also ich denke, das kann keine bevorzugte Art sein, die Zählung zu bekommen.

EDIT:

Also ich denke, der Ansatz wäre die geeignetste sein ????

So kann mir jemand effizienter einen bevorzugten Weg, dies zu tun sagen.

Danke.

Antwort

4

Jeff LaMarche verwendet dies nur als ein einfaches Beispiel. In der Praxis ist dieser Bedarf so häufig, dass die Schlüsselwertcodierung über ein integriertes Makro verfügt, um damit und anderen allgemeinen Erfassungsvorgängen umzugehen.

Siehe: The Key-Value Programming Guide: Set and Array Operators

In diesem Fall können Sie den @count Operator in Ihrem Prädikat verwenden würden.

Natürlich können Sie mit der Feinabstimmung Ihres eigenen Ausdrucks die Prädikate feinfühlig steuern, aber 80% dieser Aufgaben erledigen die Bediener.

5

Ich hatte etwa 10 000 Einheiten zu zählen und es verlangsamt meine Schnittstelle viel Reaktionsfähigkeit, während es mit countForFetchRequest tun ..

Hier ist ein Weg, um es wth NSExpression tun:

- (NSUInteger) unfilteredFCsCount { 

// Just the fetchRequest 
    NSFetchRequest *fetchRequest = [self unfilteredFCsFetchRequest]; 

    [fetchRequest setResultType: NSDictionaryResultType]; 

// You can use any attribute of the entity. its important, because you are not counting 
// the properties, but actually the entities 
    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"sortIndex_"]; // Does not really matter 
    NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:" 
                  arguments: [NSArray arrayWithObject:keyPathExpression]]; 
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
    [expressionDescription setName: @"fcCount"]; 
    [expressionDescription setExpression: maxExpression]; 
    [expressionDescription setExpressionResultType: NSInteger32AttributeType]; 

    [fetchRequest setPropertiesToFetch: [NSArray arrayWithObject:expressionDescription]]; 

    NSUInteger fcCount = 0; 
    NSError *error = nil; 
    NSArray *results = nil; 
    results = [self.managedObjectContext executeFetchRequest: fetchRequest error: &error]; 
    KSLog(KSLogLevelDebug, @"unfilteredFCsCount results: %@", results); 

    if([results count] > 0) { 
     NSNumber *count = [[results objectAtIndex: 0] objectForKey: @"fcCount"]; 
     fcCount = [count intValue]; 
    } 

    return fcCount; 
}