Подтвердить что ты не робот

Соотношение отношений CoreData со многими

Я пишу приложение iOS, в котором хранятся записи людей, и ему нужно отображать списки, отсортированные по определенным причинам. Есть переменное количество этих упорядочений, и они генерируются "на лету", но я хотел бы, чтобы они хранились в хранилище данных. Способ SQL для этого состоит в том, чтобы иметь таблицу ListPositions со списком, идентификатором в таблице лиц и ключ сортировки. Затем, чтобы отобразить конкретный список, я могу выбрать весь список ListPositions с заданным именем, потянуть ссылочных лиц и отсортировать по клавише сортировки. Попытка сделать это в CoreDatat, однако я столкнулся с проблемами. Я пытаюсь сделать это, используя следующую схему:

Person:
    Name
    DOB
    etc... 
    positions -->> ListPosition

ListPosition:
    listName
    sortKey
    person --> Person

Затем я могу получить все Лица в данном списке с помощью NSPredicate [NSPredicate predicateWithFormat:@"ANY positions.listName like %@", someList]; Это позволяет мне динамически добавлять списки против большого набора людей. Проблема в том, что я не могу использовать поле sortKey в ListPosition для сортировки Лица. Что NSSortDescriptor сделает это? И если невозможно отсортировать выборку по свойству одного элемента отношения to-many, что еще один способ получить несколько динамических порядков в coredata? Я показываю списки с NSFetchedResultsController, поэтому я не могу собрать списки в памяти. Мне нужно сделать это с помощью одного NSFetchRequest.

4b9b3361

Ответ 1

Вы правы - после отношения "ко многим" возвращается NSSet, который не имеет встроенной сортировки. Для получения отсортированных результатов есть несколько вариантов:

  • Предполагая, что Person/ListPosition является двусторонним отношением, выполните новый запрос выборки для объектов ListPosition. Сделайте соответствие предиката в отношении "person" от ListPosition, которое будет выглядеть примерно как [NSPredicate predicateWithFormat:@"person=%@", myPerson]. Используйте любой дескриптор сортировки, который вам нужен в запросе выборки.
  • Следуйте за отношениями, которые вы делаете, что дает вам NSSet. Затем используйте метод NSSet -sortedArrayUsingDescriptors:, чтобы преобразовать его в отсортированный массив.

Ответ 2

Я думаю, что лучший подход в этом случае состоял бы в том, чтобы извлечь объект ListPosition. Добавьте дескриптор сортировки для sortKey (он будет работать в этом случае, потому что запрос выборки находится в объекте ListPosition) и предварительно выберите Person, связанный с именем списка, с помощью setRelationshipKeyPathsForPrefetching для "person" в запросе выборки.

[NSPredicate predicateWithFormat:@"listName like %@", someList];

Ответ 3

Если я правильно понимаю вашу модель, каждый Person имеет один ListPosition для каждого списка, в котором он участвует. Предположим, что у нас есть список кандидатов по их именам, поэтому у X людей есть позиции списка X с теми же listName и sortKey.

Я бы создал объект List, который будет содержать атрибут sortKey, а затем использовать его в дескрипторе сортировки.

entity List:
    - sortKey : string
    - ascending : bool

Создайте дескриптор сортировки и используйте его в запросе выборки:

[NSSortDescriptor sortDescriptorWithKey:chosenList.sortKey ascending:chosenList.ascending];

Тогда у вас может быть столько списков, сколько вы хотите, и вы можете легко использовать его ключ сортировки для сортировки всех людей.


Если вы хотите сохранить позиции в базе данных (вы не указали атрибут index в своем ListPosition или что-то подобное), вы можете создать "совместную сущность":

entity PersonInList:
    - index : integer
    - person -> Person
    - list –> List

Другая идея - упорядочить набор объектов Person непосредственно в объекте List.

Ответ 4

Получить ListPosition (он появится как NSMutableSet). Затем выполните сортировку в Set, например:

NSMutableSet *positionsSet = [personEntity mutableSetValueForKey:@"positions"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"yourSortKey" ascending:NO];
NSArray *positionsSortedSet = [positionsSet sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

Это даст вам отсортированный массив в соответствии с вашим ключом.

Ответ 5

Обычно я добавляю индексное поле (тип NSNumber) к сущности. Очень легко вычислить индекс при добавлении элемента. просто

object.index = person.positions.count

так что на самом деле вам не нужны поля позиций, а позиции отношения. связать сущность лица с объектом ListPosition будет достаточно.