Pytanie CoreData sortuje na wiele związków


Piszę aplikację na iOS, która ma zapisy osób i musi wyświetlać listy, posortowane w określony sposób. Istnieje zmienna liczba tych porządków i generowane są one w locie, ale chciałbym, aby były przechowywane w magazynie danych. Sposób SQL to wykonanie tabeli ListPositions z nazwą listy, identyfikatorem w tabeli osób i kluczem sortowania. Następnie, aby wyświetlić konkretną listę, mogę wybrać całą listę ListaPozycje o danej nazwie, wciągnąć osoby, do których się odwołuję i posortować na kluczu sortowania. Próbuję to zrobić w CoreDatat, jednak mam problemy. Próbuję to zrobić za pomocą schematu, takiego jak:

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

ListPosition:
    listName
    sortKey
    person --> Person

Następnie mogę uzyskać wszystkie osoby z danej listy z NSPredicate [NSPredicate predicateWithFormat:@"ANY positions.listName like %@", someList]; To pozwala mi dynamicznie dodawać listy do dużego zbioru Osób. Problem polega na tym, że nie mogę użyć pola sortKey z ListPosition do sortowania Osób. Co zrobi to NSSortDescriptor? A jeśli nie jest możliwe sortowanie pobierania na własność jednego elementu relacji "to-wiele", to w jaki inny sposób uzyskać wiele dynamicznych porządków w cedrach? Wyświetlam listy za pomocą NSFetchedResultsController, więc nie mogę umieścić list razem w pamięci. Muszę to zrobić za pomocą pojedynczego NSFetchRequest.


12
2018-02-06 20:29


pochodzenie


ładniejsze formatowanie znacznie ułatwiłoby odczytanie tego pytania. - vikingosegundo
daj nam kod! - vikingosegundo


Odpowiedzi:


Masz rację - po stosunku to-wiele zwraca NSSet, który nie ma wrodzonego sortowania. Aby uzyskać posortowane wyniki, dostępnych jest kilka opcji:

  1. Zakładając, że Person / ListPosition jest relacją dwukierunkową, wykonaj nowe żądanie pobierania dla obiektów ListPosition. Ustaw predykat na relacji "osoba" z ListPosition, która wyglądałaby podobnie [NSPredicate predicateWithFormat:@"person=%@", myPerson]. Użyj dowolnego deskryptora sortowania na żądanie pobierania.
  2. Podążaj za związkiem tak, jak to robisz, co daje NSSet. Następnie użyj NSSet -sortedArrayUsingDescriptors: metoda konwersji tego na posortowaną tablicę.

3
2018-02-06 22:03



Nie byłem jasny. Mój problem polega nie na sortowaniu obiektów w relacji wiele do wielu, ale raczej na zapewnieniu wielu różnych porządków sortowania dla dużego zestawu obiektów. Zmieniłem to pytanie. - wombat57


Myślę, że najlepszym rozwiązaniem w tym przypadku byłoby pobranie obiektu ListPosition. Dodaj deskryptor sortowania dla sortKey (działałoby w tym przypadku, ponieważ żądanie pobierania jest w obiekcie ListPosition) i wstępnie pobierze osobę powiązaną z nazwą listy przy użyciu metody setRelationshipKeyPathsForPrefetching dla "osoby" w żądaniu pobierania.

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

1
2017-09-13 05:13



Działa to jednak, jeśli wprowadzisz jakiekolwiek zmiany w obiekcie Person, to nie spowoduje to zmiany NSFetchedResultsController, ponieważ nie zmieniła się pozycja ListPosition. - Andrew Theis


Jeśli dobrze rozumiem Twój model, każdy Person ma jeden ListPosition dla każdej listy, w której uczestniczy. Załóżmy, że mamy listę acsending po swoich nazwach, więc X ludzie mają pozycje na liście X z to samo  listName i sortKey.

Stworzyłbym byt List, który zawierałby sortKey atrybut, a następnie użyj go w deskryptorze sortowania.

entity List:
    - sortKey : string
    - ascending : bool

Utwórz deskryptor sortowania i użyj go w żądaniu pobierania:

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

Następnie możesz mieć tyle list, ile chcesz i możesz łatwo użyć ich klucza sortowania, aby posortować wszystkie osoby.


Jeśli chcesz przechowywać pozycje w bazie danych (nie wspomniałeś o atrybucie index w Twoim ListPositionlub coś podobnego), możesz utworzyć "wspólny obiekt":

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

Innym pomysłem jest posiadanie zamówionego zestawu Personobiekty bezpośrednio w List jednostka.


1
2017-11-29 22:02





Zdobądź ListPosition (pojawi się jako NSMutableSet). Następnie wykonaj sortowanie w zestawie, na przykład:

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

To da ci uporządkowany układ według twojego klucza.


1
2017-12-18 22:11





Zazwyczaj dodajem pole indeksu (typ NSNumber) do encji. Obliczanie indeksu przy dodawaniu pozycji jest bardzo łatwe. tylko przez

object.index = person.positions.count

więc właściwie nie potrzebujesz pola pozycji, ale relacje między pozycjami. połączyć podmiot osoby z jednostką ListPosition byłoby wystarczające.


0
2017-07-24 06:28