2010-07-27 6 views
6

Estoy aprendiendo datos básicos y particularmente trabajando en la agregación.¿Cómo contar en coredatos (agregación)?

Actual lo que quiero hacer: cuente el número de registros de la tabla que está en relación-muchos con relación inversa en algunos criterios.

Actualmente estoy haciendo esto:

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"]); 

Su de Jeff lemarche.

EDITAR: y he encontrado mi solución como

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]; 

Está funcionando muy bien .Pero quiero hacer más petición de este tipo a la vez. Entonces, creo que esta no puede ser una forma preferida de obtener el conteo.

EDITAR:

Así que creo que el enfoque sería el apropiado ????

Entonces, ¿alguien puede decirme una forma más eficiente de hacerlo de esta manera?

Gracias.

Respuesta

4

Jeff LaMarche simplemente está usando esto como un ejemplo simple. En la práctica, esta necesidad es tan común que Key-Value Coding tiene una macro incorporada para manejarlo y otras operaciones de recopilación comunes.

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

En este caso habría que utilizar el operador @count en su predicado.

Por supuesto, ajustar manualmente su propia expresión le da un control fino sobre sus predicados, pero los operadores manejan el 80% de dicha tarea.

5

que tenía que contar con unos 10 000 entidades y se ralentizó mi interfaz de respuesta mucho mientras lo hace con countForFetchRequest ..

Aquí es una manera de hacerlo wth NSExpression:

- (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; 
}