如何管理 Core Data 中的一对多关系?

Posted

技术标签:

【中文标题】如何管理 Core Data 中的一对多关系?【英文标题】:How to manage one-to-many relationship in Core Data? 【发布时间】:2012-01-04 08:10:01 【问题描述】:

我很难弄清楚 Core Data 如何处理其数据库。我将用一个具体的例子来解释我的问题:

假设我们有以下架构,其中的部门拥有许多帐户(我们的地址)。

我已经使用编辑器创建了我的核心数据文件。在 CachedDepartment 类中,我添加了必要的属性,并创建了一对多关系,并且我在“我的 CachedAccount 的部门属性”中选择了“反向”。CacheAccount 也有属性,并且与“ CachedDepartment 的地址”关系。

我有以下来源(我给你 2 个头文件。其余的不包含任何感兴趣的内容):

@interface CachedAccount : NSManagedObject 
@private

@property (nonatomic, retain) NSNumber * accountID;
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) CachedDepartment *department;
@end

@class CachedAccount;

@interface CachedDepartment : NSManagedObject 
@private

@property (nonatomic, retain) NSString * departmentID;
@property (nonatomic, retain) NSString * departmentName;
@property (nonatomic, retain) NSSet *addresses;
@end

@interface CachedDepartment (CoreDataGeneratedAccessors)

- (void)addAddressesObject:(CachedAccount *)value;
- (void)removeAddressesObject:(CachedAccount *)value;
- (void)addAddresses:(NSSet *)values;
- (void)removeAddresses:(NSSet *)values;

@end

现在的问题是: -- 如何创建账户和部门对象,才能建立一对多的关系? -- 我应该如何处理CoreDataGeneratedAccessors?创建后,我应该调用CachedDepartment 的-addAddressesObject 函数还是需要制作类似anAccount.department = aDepartment 的东西? -- 在每种情况下,在创建对象时,如何确保向部门添加地址不会创建地址的双重实例并存储它?

我将不胜感激。

编辑:

应该为 CachedDepartment 实体插入新对象,代码如下所示:

NSManagedObject *cachedDepartment= [NSEntityDescription
    insertNewObjectForEntityForName:@"CachedDepartment" 
    inManagedObjectContext:[self managedObjectContext]];
/*
set values for failedBankInfo here
*/
NSError *error;
if (![context save:&error]) 
    NSLog(@"The following error occured: %@", [error localizedDescription]);

然后会为 cachedAccounts 添加一条新记录,它与新插入的 cachedDepartment 对象是一对多的关系:

NSManagedObject *cachedAccounts = [NSEntityDescription
    insertNewObjectForEntityForName:@"CachedAccounts" 
    inManagedObjectContext:[<b>cachedDepartment managedObjectContext</b>]];
    /*
    set values for failedBankInfo here
    */
//setting the one-to-many relationship
[cachedDepartment addCachedAccountObject:cachedAccount];
[cachedAccount setCachedDepartment:cachedDepartment];
//
NSError *error;
if (![context save:&error]) 
    NSLog(@" couldn't save: %@", [error localizedDescription]);

【问题讨论】:

【参考方案1】:

应该如何创建帐户和部门对象,以便建立一对多关系?

如果您在模型中配置了核心数据,它将自动为您填充反向关系。因此,根据您构建代码的方式,您只需输入newAccount.department = aDepartment; 即可创建您的关系和逆向关系。

CoreDataGeneratedAccessors 应该怎么做?创建后,我应该调用 CachedDepartment 的 -addAddressesObject 函数还是需要做类似anAccount.department = aDepartment 这样的东西?

是的,就是这样。请参阅上一个子答案。生成的访问器是为了以防您的程序流程使以相反的方式工作更明智,或者如果您尚未定义反向关系。

你可以的

[aDepartment addAddressesObject:anAccount];

而不是

anAccount.department = aDepartment;

但你不需要两者都做。

在创建对象的每种情况下,我如何确保将地址添加到部门不会创建地址的双重实例并存储它?

如果您确实调用了这两个方法,这将不起作用,因为关系存储为NSMutableSet,并且您不能将同一个对象多次添加到集合中。

【讨论】:

非常感谢!我想知道的另一件事是如何使用 managedObjectContext (检查我的问题中的编辑)。如您所见,我使用 [cachedDepartment managedObjectContext]。 这将是相同的 - 您的应用程序中将只有一个托管对象上下文(您可以拥有更多,但我怀疑您在这个阶段这样做!)所以使用部门对象中的一个是很好,或者如果你在同一个对象内,来自 self 的也很好。

以上是关于如何管理 Core Data 中的一对多关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 CORE DATA 中的一对多关系

在 Core Data 中有效地获取一对多关系中的最新记录

将 Core Data 中的一对多显示为一对一

如何在 Core Data 中设置一对多关系的排序?

Core Data 使用多个上下文中的新对象从后台线程订购一对多关系保存

Core Data 获取请求与 NSFetchedResultsController 的一对多关系