【问题标题】:How do I add an NSManagedObject to Core Data and specify it's "parent" object? (iPhone)如何将 NSManagedObject 添加到 Core Data 并指定它的“父”对象? (苹果手机)
【发布时间】:2010-08-30 04:22:29
【问题描述】:

好的,情况就是这样。我有两个NSManagedObjects,分别称为StoreAisle。从StoreAisle 存在一对多关系,从AisleStore 存在一对一关系。

我在 Core Data 中添加了现有的商店,我可以正常访问。我的问题是我无法弄清楚如何将Aisle 对象添加到现有的Store。我尝试获取Store,然后将Aisle 对象添加到.Aisles 集合中,我尝试使用CoreData 在Store.h 中提供的AddAislesObject: 方法,我尝试添加@ 987654335@ 对象到.Stores 设置在Aisle 对象中。

我正在查看我的 SQLite 数据库,看起来 Aisles 已成功添加,并且它们使用 Core Data 主键关联到正确的 Store。但是由于某种原因,当我尝试检索 Aisle 对象(使用获取的 Store 对象的 .Aisles 属性)时,我总是得到一个零计数 NSSet

我也尝试删除我的 .sqlite 文件,但无济于事。

有没有人有一些简单的代码,甚至是关于最好的方法的高级建议?

谢谢!

--- 更新 8/30 0917 CST

我在下面采纳了 Adam 的一些建议,我的过道肯定会正确保存到 Core Data 中。但是,当我尝试从 Store 对象访问已保存的 Aisle 时,我没有得到任何返回。在下面的代码中,您可以看到我正在使用名称和位置从 Core Data 检索现有的 Store 对象(插入时有保护措施以确保此组合是唯一的)。然后我使用一些 NSLog 调试来访问返回数组中的单个 Store,并使用 aisles 属性遍历任何通道。忽略调试循环下面的所有内容,因为我还没有完成方法。

我看到的是 aisleList 中有零个对象。

-(NSArray *)getAisleListByStore: (Store *)aStore {

// this method should return an NSArray of aisles for aStore

NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Store" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name MATCHES[c] %@ AND location MATCHES[c] %@", aStore.name, aStore.location];

[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];

NSError *error;
NSArray *storesList = [context executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];

if (storesList == nil || [storesList count] != 1) {

    // error detected
    NSLog(@"Error retrieving stores: %@", [error localizedDescription]);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Error retrieving stores" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
    [alert show];
    [alert release];
    return nil;

} else {

    // get aisles

    // debugs
    for (Store *theStore in storesList) {
        NSLog(@"Name: %@", theStore.name);
        NSLog(@"Aisle count: %d", [theStore.aisles count]);
        NSSet *aisleList = theStore.aisles;

        for (Aisle *theAisle in aisleList) {
            NSLog(@"Aisle name: %@", theAisle.name);
        }
    }

    // Store *theStore = [storesList objectAtIndex:0];

    // NSArray *aisles = (NSArray *)theStore.aisles;
    // return aisles;
}

}

【问题讨论】:

    标签: iphone objective-c core-data


    【解决方案1】:

    不需要第三张桌子。

    您可能在 Store 中有一个 NSSet*,但在 Aisle 中有一个 Store* 属性。这是遵循 Core Data 的建议,即让每个关系都具有逆向关系的一大优势。

    Store* store = [NSEntityDescription insertNewObjectForEntityForName:@"Store" inManagedObjectContext:moc];
    Aisle* aisle = [NSEntityDescription insertNewObjectForEntityForName:@"Aisle" inManagedObjectContext:moc];
    

    假设 Aisle 实体的关系 inStore 与 Store 的多对通道关系相反:

    aisle.inStore = store;
    

    您会发现 Core Data 负责关系的另一端,即将 Aisle 添加到 Store 的 NSSet。

    别忘了:

      NSError *error;
      if (![moc save:&error]) 
      {
        NSLog(@"Core Data Save error %@, %@", error, [error userInfo]);
      }
    

    使您的更改永久化。

    【讨论】:

    • 谢谢亚当。我在保存过道时使用了这种通用格式,但我根据你的例子做了一些调整。过道肯定会保存在 Core Data 中,但我仍然无法从 Store 对象中检索它们。我将在上面的原始问题中发布更多内容。
    • 问题实际上出在数据模型上。我删除它并重新创建它(没有更改),现在它工作正常。
    【解决方案2】:

    首先,您从StoreAisle 的关系实际上是称为Aisles 还是称为aislesaisle?确保所有拼写正确。此外,关系应该被称为aisles,因为它是一个关系,而不是一个实体,它是对多的。您还应该确保从AisleStore 的一对一关系(应该称为store)是一对多Store 到@987654331 的反向关系 @ 关系。那么如果你抓住一个Store 实体并使用NSSet *aisleSet = storeEntity.aisles; 你应该得到一个正确的集合。

    【讨论】:

    • Store 到 Aisle 的关系称为 aisles,我只是将 Aisle 到 Store 的关系名称更改为 inStore。它们被配置为彼此的反向关系。但是,它仍然无法正常工作。我在 SQLite 中看到了 Aisle 条目,但无法使用 Store 对象检索它。
    【解决方案3】:

    如何在这两个表之间滑动第三个表来连接它们?这会将 Stores 与 Aisles id 配对,并提供双向连接。称之为 StoreAisle。

    您有商店并且想要过道?在 store 表中找到您想要的商店,获取该商店 ID,在 StoreAisle 表中查找 Aisles 表中的通道 ID。

    您有过道并且想要商店?在通道表中找到您想要的通道,获取该 ID,然后在 StoreAisle 表中查找您在 Store 表中查找的商店 ID。

    【讨论】:

    • 我实际上已经考虑过这一点,或者至少使用 PK 标识符来编写我自己的查询,这样我就不必依赖使用 Store 对象来访问通道。不过,我认为这不是“正确”的方式。你知道我将如何检索 Core Data 生成的对象的 PKID 吗?
    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多