8

アプリに次のデータ モデルがあります。

データ・モデル

基本的に、国名と都市名を保存したいと考えています。各都市は 1 つの国に属し、1 つの国には 0 ~ n 都市が含まれます。

特定の国に新しい都市を追加する前に、その国にこの名前の都市が既に含まれているかどうかを知る必要があります。

今まで私はこれを行います:

- (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;
}

これは明らかに非常に遅いです。必要なのは、正しい述語を使用した同等のフェッチです。次のような 1 つのエンティティを検索します。

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];

しかし、検索に複数のエンティティが含まれる場合、どうすればよいでしょうか? 言い換えれば、1 つの国だけに固有の都市名を追加するにはどうすればよいですか?

4

1 に答える 1

16

指定された国オブジェクトに名前のある都市が既に含まれていることを確認したい場合は、次のことができます。

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

または、フェッチ リクエストを使用します。

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
}

aNSFetchedResultsControllerは通常、テーブル ビューでフェッチ リクエストの内容を表示するために使用されるため、ここでは必要ありません。

于 2013-05-28T11:18:15.363 に答える