繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM