检索核心数据关系的计数

时间:2013-08-25 02:33:21

标签: ios objective-c core-data nspredicate

我搜索得很高,但我找不到我想要的东西。我的问题与此类似,但略有不同:

Core Data - Count of Related Records

假设我有一个Car实体,它与Person实体有一对多的关系。这意味着汽车可能有多人驾驶它,但每个人只驾驶一辆汽车。

我希望能够只执行一个谓词,其中我可以实现以下目标:

  1. 所有'红色'汽车。
  2. 仅返回匹配车辆的“年份”和“颜色”属性。
  3. 返回驾驶这辆车的人数(即每辆车内的NSSet of People的大小)。
  4. 是否可以通过一个查询完成所有这些操作?

    我知道如何使用多个查询执行此操作。我只想使用setPropertiesToFetch并使用过滤谓词来实现上面的1和2。然后我会在每辆车的Persons实体上执行另一个计数查询(countForFetchRequest),以查找每辆车有多少人。

    关键是上面的第3个要求。我想在一个谓词中执行所有操作,并且我不希望将所有Person实体对象放入初始查询的内存(性能)中。此外,为每辆车调用另一个countForFetchRequest查询会很痛苦。

    最好的方法是什么?

    谢谢!

2 个答案:

答案 0 :(得分:3)

  1. 只返回'红色'汽车:

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"color LIKE 'red'"];
    
  2. 返回驾驶这辆车的人数:

    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"people"];
    NSExpression *countExpression = [NSExpression expressionForFunction:@"count:"
                                                              arguments:@[keyPathExpression]];
    
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    [expressionDescription setName:@"count"];
    [expressionDescription setExpression:countExpression];
    [expressionDescription setExpressionResultType:NSInteger32AttributeType];
    
  3. 仅返回'year'和'color'属性(以及计数):

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car"
                                              inManagedObjectContext:context];
    
    NSDictionary *attributes = [entity attributesByName];
    
    NSArray *properties = @[expressionDescription, attributes[@"year"], attributes[@"color"]];
    
  4. 构建并执行获取请求:

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];
    [request setResultType:NSDictionaryResultType];
    
    [request setPropertiesToFetch:properties]; // return only count, year & color
    
    [request setPredicate:predicate]; // return only red cars
    
    NSError *error = nil;
    NSArray *results = [context executeFetchRequest:request error:&error];
    
  5. 处理结果:

    if (results) {
        for (NSDictionary *result in results) {
            NSLog(@"Year: %@", result[@"year"]);
            NSLog(@"Color: %@", result[@"color"]);
            NSLog(@"Drivers: %@", result[@"count"]);
        }
    }
    else {
        NSLog(@"Error: %@", error);
    }
    

答案 1 :(得分:2)

我目前无法对此进行测试,但是应该可以通过将以下表达式描述添加到“要提取的属性”来实现:

NSExpression *countExpression = [NSExpression expressionForFunction: @"count:" arguments: [NSArray arrayWithObject:[NSExpression expressionForKeyPath: @"drivers"]]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];

[expressionDescription setName: @"driversCount"];
[expressionDescription setExpression: countExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];