После добавления setRelationshipKeyPathsForPrefetching по-прежнему отображается ошибка выборки отношения «один ко многим».

Допустим, в моей модели данных есть две сущности: отдел и человек. Отделы имеют отношение «ко многим», называемое «отделом к ​​человеку» с человеком. У Person есть однозначная связь под названием «personToDepartment» с отделом.

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

personToDepartment.departmentName == (entity: Department; id: 0x8cc1920; data: {departmentName = Marketing; DepartmentToPerson = "";

Я прочитал цель ошибок и реализовал setRelationshipKeyPathsForPrefetching, но все равно получаю ошибку. Я добавлю отказ от ответственности, что я новичок и могу упустить что-то очевидное. Когда я удаляю предикат, мое табличное представление заполняется всеми именами людей. Вот код:

- (NSFetchedResultsController *)fetchedResultsController {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                entityForName:@"Person" inManagedObjectContext:_managedObjectContext];
    [fetchRequest setEntity:entity];


    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personToDepartment.departmentName = %@", selectedDepartment];
    NSLog(@"predicate is: %@",predicate);

    [fetchRequest setPredicate:predicate];

    [fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects: @"departmentToPerson", nil]];

fetchRequest.returnsObjectsAsFaults = NO;

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                    initWithKey:@"personName" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];


    [fetchRequest setFetchBatchSize:20];


    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:_managedObjectContext sectionNameKeyPath:nil
                cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

}

Опять же, я выбираю новый отдел из UILabel, в журнале отображается selectedDepartment, но затем указывается ошибка связи и таблица не заполняется.

Заранее спасибо за помощь!

Обновлено 9 ИЮНЯ

Я также нашел это работает:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personToDepartment = %@", selectedDepartment];

person user3411663    schedule 04.06.2014    source источник


Ответы (1)


Я тоже новичок в CoreData, но мне кажется, что предикат неверен. Согласно записи журнала, вы собираетесь сравнить personToDepartment.departmentName с объектом отдела. Предикат должен выглядеть так: NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personToDepartment.departmentName = %@", selectedDepartment.departmentName];

Но есть лучший способ. selectedDepartment.departmentToPerson вернет NSSet со всеми лицами, принадлежащими к этому отделу (если отношения были установлены ранее). Но предупреждаю: если вы попытаетесь NSLog(@"%@", selectedDepartment.departmentToPerson), возможно, вы получите "ошибка связи", потому что CoreData не будет выполнять выборку, пока вы не обратитесь к конкретному объекту в NSSet или не проведете через него перечисление. Но, например, NSLog(@"%d", selectedDepartment.departmentToPerson.count) заставит CoreData выполнить выборку, и вы увидите количество человек в отделе.

ОБНОВЛЕНИЕ: NSSet пуст, вероятно, потому, что вы не устанавливаете отношения при создании объекта человека. Обратное отношение «ко многим» от отдела к лицам будет установлено автоматически.

- (id)insertNewPerson:(NSDictionary *)personInfo inDepartment:(Department*)departmentObject 
{
    Person *personObject = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
    personObject.name = personInfo.name;
    personObject.departmentName = departmentObject.name;
    ...
    personObject.personToDepartment = departmentObject;   //this is RELATIONSHIP, if set, then you can access all persons from specific department by doing: departmentObject.departmentToPerson
}
person bucherland    schedule 04.06.2014
comment
bucherland это именно то, что нужно, спасибо! Я потратил много времени на устранение неполадок. Я соглашусь, поскольку это отвечает на мой первый вопрос. Теперь я попробовал подход NSSet с предикатом, но ничего не возвращает. Есть ли что-то еще, что мне нужно добавить в выборку для этого? NSLog for count работает. - person user3411663; 04.06.2014
comment
Рад, что это помогает. selectedDepartment.departmentToPerson не работает, потому что, вероятно, вы не устанавливаете отношения при создании Person. (Значение NSLog пусто). - person bucherland; 05.06.2014