2012-12-06 38 views
5

我需要做从我的核心数据存储两个表/车型“加盟”型操作,而且我有困难的时候找到很好的例子了那里得到的东西喜欢这个工作。核心数据 - 简单连接型取

这是相当简单的什么,我需要做的。我有两个模型/表:location和location_categories,其中位置包含位置/建筑的详细信息(以及唯一的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循环?我目前的Objective-C代码是在下面,它工作正常,但由于两个表中都有大量数据,所以它当然非常慢并且效率低下。在for循环都造成了巨大的经济放缓,我的直觉告诉我,这工作真的应该对事物的DB /核心数据面来完成:

- (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; 
} 

这是否有可能与一个单一的任何想法谓词/取?或者不知道..也许有一种更有效的方式通过Objective-C代码加入这两个NSArrays?

预先感谢您可以在此提供任何方向!

回答

3

,最好的办法是使用关系。

,当你取一个Location您还可以访问LocationCategorymyLocation.locationCategory

您需要设置您的relationsship像这样这样:

(Entity)LocationCategory.(relationship)locations <->> (Entity)Location.(relationship)locationCategory 

这是一个一对多的关系。不要忘记反过来。

一旦设置完成,您只需将关系连接到您创建实体实例的地方。像:

Location *myLocation = ... 
LocationCategory *myLocationCategory = ... 
myLocation.locationCategoy = myLocationCategory; 

此外请确保您使用相同的MOC来获取对象。我强烈建议MagicalRecord轻松管理创建对象并在指定的moc中获取。

+0

将此标记为最佳答案,因为您提到需要连接关系。即使在模型中实现了关系之后,这仍然让我犹豫不决。谢谢! – svguerin3

2

阅读关于核心数据和关系。它会自动创建一组相关实体的其他对象。因此,在上述情况下,如果您将位置作为一个实体,将Location_Categories作为另一个类别,则只需在位置表中创建一个指向位置类别实体的关系即可。

可以在核心数据建模屏幕做到这一点。

一旦你这样做了,Location Managed Object类将有一个NSSet的Location类别。同样,位置类别实体将在其中包含位置对象。

因此,所有你需要做的是,就像你在上面怎么办地点分类的一个查询。但不要做额外的查询,你需要做

for (LocationCategory *locationCategory in locationCats) { 
    NSLog(@"Location name is %@",locationCategory.location.locationName); 
    // You can ofcourse add it to an arrary or what ever 
} 

任何核心数据教程应该能够帮助你。

+0

辉煌,谢谢!我觉得自己是一个白痴,以避免在我的模型中使用关系。我认为没有多少意义,但现在我明白了这一点。 :)我不知道可以用这种方式来使用关系(我对Core Data相当陌生)。现在工作正常。再次感谢您的帮助和时间! – svguerin3

1

如果这些实体是在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