1

我到处搜索,但找不到我要找的确切内容。我的问题与此类似,但略有不同:

核心数据 - 相关记录数

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

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

  1. 所有“红色”的汽车。
  2. 仅返回匹配汽车的“年份”和“颜色”属性。
  3. 返回有多少人正在驾驶这辆车的计数(即每辆生成的车内的人的 NSSet 的大小)。

是否可以通过一个查询完成所有这些操作?

我知道如何通过多个查询来做到这一点。我只会使用setPropertiesToFetch过滤谓词来实现上面的 1 和 2。然后,我将对countForFetchRequest每辆车的 Persons 实体执行另一个计数查询 (),以查找每辆车有多少人驾驶。

关键是上面的第三个要求。我想在一个谓词中做所有事情,我不想在初始查询时将所有 Person 实体对象都带入内存(性能)。countForFetchRequest此外,为每辆车调用另一个查询会很痛苦。

最好的方法是什么?

谢谢!

4

2 回答 2

3

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

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];
于 2013-08-25T07:38:57.390 回答
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);
    }
    
于 2013-08-26T03:05:24.280 回答