2013-08-25 2 views
1

Я искал высокий и низкий, но я не мог найти то, что искал. Мой вопрос похож на это, но немного иначе:Получение отсчета отношения данных ядра

Core Data - Count of Related Records

Допустим, у меня есть сущность автомобиля, который имеет один ко многим отношения с человеком, лица. Это означает, что автомобиль может иметь несколько человек, ведущих его, но каждый человек ездит только на одном автомобиле.

Я хочу, чтобы быть в состоянии выполнить только один предикат, в котором я мог бы достичь следующий:

  1. Всех автомобилей, которые являются «красными».
  2. Возвратите только атрибуты «Год» и «Цвет» соответствующего автомобиля.
  3. Возвратите количество людей, которые управляют этим автомобилем (т. Е. Размер NSS-набора людей внутри каждого результирующего автомобиля).

Возможно ли это сделать одним запросом?

Я знаю, как это сделать с несколькими запросами. Я бы просто использовал setPropertiesToFetch и использовал отфильтрованный предикат для достижения 1 и 2 выше. Затем я выполнил другой запрос подсчета (countForFetchRequest) об объекте Лица для каждого автомобиля, чтобы узнать, сколько Лица (ов) водит каждый автомобиль.

Ключ является третьим требованием выше. Я хочу сделать все в одном предикате, и я не хочу приносить все объекты объекта Person в память (производительность) в исходный запрос. Кроме того, больно звонить другому запросу countForFetchRequest для каждого автомобиля.

Каков наилучший способ для этого?

Спасибо!

ответ

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

Вам также необходимо отправить '[fe tchRequest setResultType: NSDictionaryResultType]; ', и после создания выраженияDescription вы вызываете' [fetchRequest setPropertiesToFetch: @ [выражениеDescription]]; ' – Abizern

+0

@Abizern: Вы, конечно, правы. Но OP в своем вопросе сказал, что он уже знает, как использовать setPropertiesToFetch для извлечения атрибута year и color, поэтому я пропустил эту часть. –

+1

Просто заполните его для следующего человека, который смотрит на этот вопрос и видит ваш ответ :) – Abizern

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. Возврат только 'год' и 'цвет' атрибуты (и количество):

    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); 
    } 
    
Смежные вопросы