Выборка и сортировка объектов в Core Data

Допустим, у меня есть модель, аналогичная приведенной ниже, и мне нужно получить всех «лиц» определенного Company.companyName, отсортированных по personRole.roleWeight.

Вот такая модель у меня на данный момент:

  • Субъект: Компания
  • Атрибуты: название компании
  • Отношения: компанияРоль

  • Сущность: Роль

  • Атрибуты: имя_роли, вес_роли.
  • Отношения: rolePerson, RoleCompany

  • Сущность: Человек

  • Атрибуты: имя человека
  • Отношения: человек Роль

Вот простая схема отношений:

Компания --‹ Роль >--‹ Лицо

Есть ли способ сделать это? Если мне нужно изменить модель, я был бы рад это сделать. Все предложения приветствуются.

Спасибо,


person Benjamin Ortuzar    schedule 01.07.2010    source источник


Ответы (2)


arrow_upward
1
arrow_downward

Вы не можете сортировать по весу роли, потому что может быть более одной подходящей роли.

Вы также не можете прийти к этому из роли (в отличие от человека), потому что у вас есть много ко многим между ролью и человеком.

Вы должны переосмыслить свой дизайн, потому что многие ко многим не имеют особого смысла. Небольшая денормализация данных, изменение отношения «многие ко многим» на «один ко многим» и дублирование значений имени роли и веса роли решит проблему.

Обновлять

Предположим, вы изменили дизайн на:

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 для сбора всех объектов-лиц на другом конце отношения, которые будут извлекаться по порядку.

person Marcus S. Zarra    schedule 02.07.2010
comment
Привет, Маркус, у человека может быть только 1 должность в определенной компании. Можно ли получить объекты ролей для конкретной компании и из этих ролей получить людей, которые с ними связаны? Моя главная цель - иметь возможность сортировать людей в компании по весу их ролей в этой компании, возможно, вы можете предложить мне лучший дизайн, который облегчит эту задачу. Большое спасибо. - person Benjamin Ortuzar; 02.07.2010

arrow_upward
0
arrow_downward

Есть ли причина, по которой Роль — это обезьяна посередине, а не человек? Это облегчило бы эту задачу, но, возможно, у вас есть другие действия, которые вы делаете с данными, что исключает этот вариант. Если бы у каждого человека была одна роль и одна компания, вы могли бы создать дескриптор сортировки для role.roleWeight и использовать метод NSSet sortedArrayUsingDescriptors: для набора отношений сотрудников рассматриваемой компании. Это даст вам новый отсортированный массив со списком всех сущностей Person, прикрепленных к данной компании, отсортированных по roleWeight (вы можете включить дополнительный дескриптор сортировки, чтобы позаботиться о сопоставлении roleWeights).

person theMikeSwan    schedule 20.07.2010