2012-10-05 10 views
6

Ustawienia: Mam kolekcję obiektów nadrzędnych, nazywam je ObjectA. Każdy obiekt A ma relację jeden-do-wielu do ObjectB. Zatem jeden obiekt ObjectA może zawierać 0..n ObjectB-ów, a każdy obiekt B ma określony obiekt ObjectA jako jego obiekt nadrzędny.Jak sortować wyniki danych podstawowych na podstawie atrybutu zbierania powiązanych obiektów?

Teraz chciałbym pobrać Core Data z ObjectA-s, gdzie są sortowane według ich najnowszego ObjectB. Czy jest możliwe utworzenie deskryptora sortowania?

Istnieje a related question, który opisuje dokładnie tę samą sytuację. Odpowiedź sugeruje denormalizowanie atrybutu z ObjectB do ObjectA. Byłoby OK, gdyby naprawdę nie było sposobu, aby to zrobić z jedną prośbą o pobranie.

Odnośne pytanie wspomina również:

Actually, I just had an idea! Maybe I can sort Conversations by [email protected]

próbowałem. To nie wydaje się możliwe. Otrzymuję ten błąd:

2012-10-05 17:51:42.813 xxx[6398:c07] *** Terminating app due to uncaught 
exception 'NSInvalidArgumentException', reason: 'Keypath containing 
KVC aggregate where there shouldn't be one; failed to handle 
[email protected]' 

Czy denormalizacja atrybutu w ObjectA jest jedynym/najlepszym rozwiązaniem?

Odpowiedz

0

Można dodać atrybut w objectB która jest datownik z datą dodawać, potem w pobrać wniosek można zrobić coś takiego:

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"objectB.addTime" ascending:YES]; 
... 
fetchRequest.sortDescriptors = @[descriptor]; 
+2

To nie zadziałało dla mnie: "NSInvalidArgumentException", powód: "klucz do wielu nie jest tutaj dozwolony" –

0

wiem, to pytanie jest nieco stary, ale co Zrobiłem to zdobyć wszystkie ObjectB, iterować wyniki i wyciągnąć właściwość ObjectB i dodać ją do nowej tablicy.

NSFetchRequest *fetchRequest = [NSFetchRequest new]; 
[fetchRequest setEntity:self.entityDescForObjectB]; 

// sort 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES]; 
[fetchRequest setSortDescriptors:@[sortDescriptor]]; 

NSError *error = nil; 
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
if (fetchedObjects == nil) { 
    NSLog(@"Error fetching objects: %@", error.localizedDescription); 
    return; 
} 

// pull out all the ObjectA objects 
NSMutableArray *tmp = [@[] mutableCopy]; 
for (ObjectB *obj in fetchedObjects) { 
    if ([tmp containsObject:obj.objectA]) { 
     continue; 
    } 
    [tmp addObject:obj.objectA]; 
} 

Działa to, ponieważ CoreData jest wykresem obiektów, dzięki czemu można pracować wstecz. Pętla na końcu sprawdza, czy tablica tmp ma już określoną instancję klasy ObjectA, a jeśli nie, dodaje ją do tablicy.

Ważne jest, aby posortować obiekty ObjectB, w przeciwnym razie to ćwiczenie jest bezcelowe.

Powiązane problemy