[英]Core Data - Simple JOIN-type Fetch
我需要在我的Core Data存储中的两个表/模型上进行“连接”类型的操作,而我很难找到好的例子来获得这样的东西。
我需要做的事情相当简单。 我有两个模型/表:locations和location_categories,其中locations包含位置/企业的详细信息(以及唯一的ID),location_categories表包含category_id和关联的location_id。 我需要选择所有位置,给定category_id,它连接两个表/模型。 如果它是直接SQL,它看起来像这样(当我针对实际的SQLite DB运行它时,此查询确实有效):
// pretend we passed in a catID of 29:
SELECT * FROM zlocation where zlocid in (select zlocid from zloccategory where zcatid = 29)
所以你可以看到,它非常简单。 有没有办法做到这一点,而不必做两个提取和for循环? 我目前的目标-c代码如下所示,它工作正常,但由于两个表中有大量数据,它当然非常慢且效率低下。 for循环导致了一个巨大的减速,我的直觉告诉我,这项工作确实应该在DB / Core-Data方面完成:
- (NSMutableArray *) fetchLocsWithCatID:(NSString *)catID {
NSMutableArray *retArr = [[NSMutableArray alloc] init];
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:MODELNAME_LOCCATEGORIES inManagedObjectContext:context]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat:@"catID == %@", catID]];
NSError *error;
NSArray *locCats = [context executeFetchRequest:fetchRequest error:&error];
NSArray *allLocsArr = [self fetchAllDataForTable:MODELNAME_LOCATION]; // this retrieves contents of entire table
for (Location *currLoc in allLocsArr) {
for (LocCategory *currLocCat in locCats) {
if ([currLoc.locID isEqualToString:currLocCat.locID]) {
if (![retArr containsObject:currLoc]) {
[retArr addObject:currLoc];
}
}
}
}
return retArr;
}
有关单一谓词/提取是否可行的任何想法? 或者dunno ..也许有更有效的方法通过objective-c代码加入这两个NSArray?
提前感谢您提供的任何方向!
最好的方法是使用关系。
这样,当您获取Location
您也可以像myLocation.locationCategory
一样访问LocationCategory
你需要像这样设置你的关系:
(Entity)LocationCategory.(relationship)locations <->> (Entity)Location.(relationship)locationCategory
这是一种多对多的关系。 也不要忘记逆。
一旦设置完毕,您只需要在创建实体实例的地方连接关系。 喜欢:
Location *myLocation = ...
LocationCategory *myLocationCategory = ...
myLocation.locationCategoy = myLocationCategory;
还要确保使用相同的MOC来获取对象。 我强烈建议MagicalRecord轻松管理创建对象并在指定的moc中获取。
阅读核心数据和关系。 它将自动创建相关实体的其他对象集。 因此,在您的上述情况下,如果您将Locations作为一个实体,Location_Categories作为另一个类别,您需要做的就是在Locations表中创建一个指向Location Categories实体的关系。
您可以在Core Data Modeling屏幕中执行此操作。
执行此操作后,Location Managed Object类将具有NSSet of Location Categories。 同样,位置类别实体将在其中包含位置对象。
因此,您需要做的就是查询位置类别,就像上面的操作一样。 但是,您需要做的不是进行其他查询
for (LocationCategory *locationCategory in locationCats) {
NSLog(@"Location name is %@",locationCategory.location.locationName);
// You can ofcourse add it to an arrary or what ever
}
任何核心数据教程都应该能够为您提供帮助。
如果这些实体在CoreData中建模,您通常会有一个从location_categories到位置的关联,从location到location_categories具有反向关系。 因此,如果我有一个名为“Location”的实体,它将在其中建立一个名为locationCategory的关系,而在LocationCategory实体中,它将具有一个名为Location的关系。
通过定义这种双向关系,我将使用以下内容设置我的获取请求:
[fetchRequest setEntity:[NSEntityDescription entityForName:MODELNAME_LOCATIONS inManagedObjectContext:context]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat:@"locationCategory.catID == %@", catID]];
这应该返回与具有给定类别ID的位置类别相关联的所有Location对象
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.