Допустим, у меня есть модель, аналогичная приведенной ниже, и мне нужно получить всех "лиц" определенного Company.companyName, отсортированных по personRole.roleWeight.
Вот такая модель у меня на данный момент:
Вот простая схема отношений:
Компания --‹ Роль >--‹ Лицо
Есть ли способ сделать это? Если мне нужно изменить модель, я был бы рад это сделать. Все предложения приветствуются.
Спасибо,
Ответ 1 · рейтинг 1 · Marcus S. Zarra
Вы не можете сортировать по весу роли, потому что может быть более одной подходящей роли.
Вы также не можете прийти к этому из роли (в отличие от человека), потому что у вас есть много ко многим между ролью и человеком.
Вы должны переосмыслить свой дизайн, потому что многие ко многим не имеют особого смысла. Небольшая денормализация данных, изменение отношения "многие ко многим" на "один ко многим" и дублирование значений имени роли и веса роли решит проблему.
Обновлять
Предположим, вы изменили дизайн на:
Company --< Role >-- Person
Тогда решение становится намного проще:
- (NSArray*)peopleSortedByWeightInCompany:(NSString*)company inManagedObjectContext:(NSManagedObjectContext*)moc
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Role" inManagedObjectContext:moc]];
[request setPredicate:[NSPredicate predicateWithFormat:@"company.name == %@", companyName]];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"weight" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sort]];
NSError *error = nil;
NSArray *roles = [moc executeFetchRequest:request error:&error];
[request release], request = nil;
NSAssert2(roles != nil && error == nil, @"Error fetching roles: %@\n%@", [error localizedDescription], [error userInfo]);
NSArray *people = [roles valueForKeyPath:@"@distinctUnionOfObjects.person"];
return people;
}
Вы в основном выбираете объекты ролей, отсортированные по весу и отфильтрованные по названию компании. Затем из этого массива сущностей ролей вы используете KVC для сбора всех объектов-лиц на другом конце отношения, которые будут извлекаться по порядку.
Ответ 2 · theMikeSwan
Есть ли причина, по которой Роль - это обезьяна посередине, а не человек? Это облегчило бы эту задачу, но, возможно, у вас есть другие действия, которые вы делаете с данными, что исключает этот вариант. Если бы у каждого человека была одна роль и одна компания, вы могли бы создать дескриптор сортировки для role.roleWeight и использовать метод NSSet sortedArrayUsingDescriptors: для набора отношений сотрудников рассматриваемой компании. Это даст вам новый отсортированный массив со списком всех сущностей Person, прикрепленных к данной компании, отсортированных по roleWeight (вы можете включить дополнительный дескриптор сортировки, чтобы позаботиться о сопоставлении roleWeights).