核心数据 - 简单的JOIN类型获取

svg*_*in3 5 iphone core-data objective-c ios

我需要在我的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)
Run Code Online (Sandbox Code Playgroud)

所以你可以看到,它非常简单.有没有办法做到这一点,而不必做两个提取和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;
}
Run Code Online (Sandbox Code Playgroud)

有关单一谓词/提取是否可行的任何想法?或者dunno ..也许有更有效的方法通过objective-c代码加入这两个NSArray?

提前感谢您提供的任何方向!

mkr*_*ral 3

最好的方法是利用关系。

这样,当您获取 a 时,Location您还可以访问LocationCategory类似的内容myLocation.locationCategory

您需要像这样建立您的关系:

(Entity)LocationCategory.(relationship)locations <->> (Entity)Location.(relationship)locationCategory
Run Code Online (Sandbox Code Playgroud)

这是一种一对多的关系。也不要忘记相反的情况。

设置完成后,您只需在创建实体实例的位置连接关系即可。喜欢:

 Location *myLocation = ...
 LocationCategory *myLocationCategory = ...
 myLocation.locationCategoy = myLocationCategory;
Run Code Online (Sandbox Code Playgroud)

还要确保您使用相同的 MOC 来获取对象。我强烈推荐MagicalRecord来轻松管理创建对象并在指定的 moc 中获取。