2013-05-28 14 views
7

Mam następujący model danych w mojej aplikacji:CoreData sprawdzić, czy do-wielu-relacji zawiera obiekt

data model

Zasadniczo chcę zapisać nazwy krajów aswell jak nazwy miast. Każde miasto należy do jednego kraju, a jeden kraj zawiera 0 - n miast.

Zanim dodaję nowe miasta do określonego kraju, muszę wiedzieć, czy kraj zawiera już miasto o tej nazwie.

Do tej pory mam to zrobić:

- (BOOL)countryForName:(NSString *)countryName containsCity:(NSString *)cityName { 
    Countries *country = [self countryForName:countryName]; 
    NSSet *cityNames = [country valueForKey:@"cities"]; 
    for (Cities *city in cityNames) { 
     if ([city.cityName isEqualToString:cityName]) { 
      return YES; 
     } 
    } 
    return NO; 
} 

To oczywiście jest bardzo powolny, co potrzebne jest odpowiednikiem sprowadzić z właściwej orzecznika. I przeprowadzić wyszukiwanie do jednego podmiotu takiego:

NSEntityDescription *entity  = [NSEntityDescription entityForName:@"Countries" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"countryName" ascending:YES]; 
    NSArray *sortDescriptors   = @[sortDescriptor]; 
    fetchRequest.sortDescriptors  = sortDescriptors; 

    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"GetCountryList"]; 
    aFetchedResultsController.delegate = self; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"countryName == %@", countryName]; 
    [aFetchedResultsController.fetchRequest setPredicate:predicate]; 

Ale jak to zrobić, jeśli wyszukiwanie obejmuje wiele podmiotów? Lub innymi słowy: Jak dodać unikalne nazwy miast tylko w jednym kraju?
Dziękuję bardzo!

Odpowiedz

11

Jeśli chcesz sprawdzić, czy dany przedmiot kraj zawiera już miasto o nazwie można zrobić

Countries *country = ... 
NSString *cityName = ... 
if ([[country valueForKeyPath:@"cities.name"] containsObject:cityName]) { 
    // ... 
} 

Lub przy wniosek pobierał:

NSString *countryName = ... 
NSString *cityName = ... 
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Countries"]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"countryName == %@ AND ANY cities.cityName == %@", countryName, cityName]; 
[fetchRequest setPredicate:predicate]; 

NSError *error; 
NSUInteger count = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error]; 

if (count == NSNotFound) { 
    // error 
} else if (count == 0) { 
    // no matching country 
} else { 
    // at least one matching country 
} 

pamiętać, że NSFetchedResultsController jest zwykle używany do wyświetlania zawartości żądania pobrania w widoku tabeli, więc nie jest tutaj potrzebny.

+0

Cześć Martin, dziękuję za tę odpowiedź. To rozwiązanie wygląda tylko na bardzo małą poprawę mojego kodu. Czy nie ma sposobu, aby utworzyć żądanie pobrania, a następnie wykonać 'countForFetchRequest:' zwracając 0 dla "kraj nie zawiera tego miasta" lub wartość> 0 dla "kraju zawiera to miasto"? Naprawdę nie lubię tworzyć obiektów w celu zmniejszenia zużycia pamięci ... – pmk

+0

@ pmk: Masz rację. Zaktualizowałem odpowiedź. –

+0

Właśnie przetestowałem twój kod, teraz działa idealnie. Edytowałem Twój kod odpowiedzi, aby inni mogli z niego korzystać, dziękuję bardzo :) – pmk

Powiązane problemy