CoreData 检查多对多关系是不是包含对象
Posted
技术标签:
【中文标题】CoreData 检查多对多关系是不是包含对象【英文标题】:CoreData check if to-many-relationship contains objectCoreData 检查多对多关系是否包含对象 【发布时间】:2013-05-28 09:47:48 【问题描述】:我的应用中有以下数据模型:
基本上我想存储国家名称和城市名称。每个城市属于一个国家,一个国家包含 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;
这显然很慢,我需要的是具有正确谓词的等效提取。我搜索一个这样的实体:
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】:如果你想检查一个给定的国家对象是否已经包含一个有名字的城市, 你可以做
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
请注意,NSFetchedResultsController
通常用于显示
在表格视图中获取请求,因此这里不需要。
【讨论】:
嗨,马丁,感谢您的回复。这个解决方案看起来对我的代码只有很小的改进。有没有办法创建一个 fetchrequest 然后执行countForFetchRequest:
为“国家不包含这个城市”返回 0 或为“国家包含这个城市”返回一个 > 0 的值?我真的不喜欢创建对象以减少内存使用...
我刚刚测试了你的代码,现在可以完美运行了。我编辑了您的答案代码,以便其他人可以利用它,非常感谢:)
@pmk:不客气(是的,代码中有一些愚蠢的错误)。 - 我刚刚重新插入了便捷方法fetchRequestWithEntityName
(现在希望是正确的),它节省了 2 行代码。
假设您有一个数组 cityNames ['CityA', 'CityB', 'CityC']。您将如何获取包含数组中所有城市或其中一个城市的国家/地区?以上是关于CoreData 检查多对多关系是不是包含对象的主要内容,如果未能解决你的问题,请参考以下文章
CoreData :NSFetchedResultsController 一对多对多的关系
Swift、CoreData 和多对多关系:如何访问子项的顺序?