CoreData检查to-many-relationship是否包含对象

pmk*_*pmk 7 core-data one-to-many nspredicate

我的应用程序中有以下数据模型:

数据模型

基本上我想存储国家名称以及城市名称.每个城市属于一个国家,一个国家包含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;
}
Run Code Online (Sandbox Code Playgroud)

这显然非常慢,我需要的是具有正确谓词的等效提取.我执行搜索这样的一个实体:

    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];
Run Code Online (Sandbox Code Playgroud)

但是,如果搜索涉及多个实体,我该怎么做?或者换句话说:如何仅为一个国家/地区添加唯一城市名称?
非常感谢你!

Mar*_*n R 14

如果要检查给定的国家/地区对象是否已包含具有名称的城市,则可以执行此操作

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

或者,使用获取请求:

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
}
Run Code Online (Sandbox Code Playgroud)

请注意,a NSFetchedResultsController通常用于在表视图中显示获取请求的内容,因此这里不需要它.

  • @pmk:不客气(是的,代码中存在一些愚蠢的错误)。- 我刚刚重新插入了便捷方法“fetchRequestWithEntityName”(现在希望是正确的),这节省了 2 行代码。 (2认同)