在导入核心数据的同时建立关系?
Posted
技术标签:
【中文标题】在导入核心数据的同时建立关系?【英文标题】:Setting up relationships while importing core data? 【发布时间】:2009-10-20 03:05:27 【问题描述】:我有一个名为 importMoc 的内存托管对象上下文,用于导入记录(例如员工)。我已经解析了一个文件并在 importMoc 中设置了员工对象,但有一个非常重要的例外。用户确认他们想要处理 %d 名员工,但我不太清楚如何或何时设置员工的“父”关系(例如设置他们的部门)。
出于我的目的,它们都将被导入同一个部门(用户已经隐式选择)。
显然,我无法在两个上下文之间建立关系,我也是:
-
在 importMoc 中创建一个部门,然后在我合并更改时将“导入”部门与“真实”部门合并?
2) 合并员工,然后获取所有新导入的员工(不知何故!!!)然后设置他们的部门?
3) 我忽略了其他一些解决方案?
这似乎是一个简单的问题,但出于某种原因(懒惰?疲倦?愚蠢?)我不知道该怎么做!到目前为止,我尝试过的一切似乎都过于复杂和复杂!
提前致谢!
【问题讨论】:
【参考方案1】:如果Department
对象已经保存到持久存储中,那么您可以将它们带入另一个托管对象上下文。由于您的对象无论如何都必须存在于同一个持久存储中(因为不允许跨存储关系),您应该能够简单地将您需要的对象提取到importMoc
。
例如:
foreach (NSDictionary *record in employeeRecords)
NSManagedObject *employee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:importMoc];
// Configure employee however you do that
NSString *managerID = [record objectForKey:@"someKeyThatUniquelyIdentifiesTheManager"];
NSFetchRequest *managerFetchRequest = [[NSFetchRequest alloc] init];
[managerFetchRequest setEntity:[NSEntity entityForName:@"Manager" inManagedObjectContext:importMoc]];
[managerFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"managerProperty == %@", managerID]];
NSArray *managers = [importMoc executeFetchRequest:managerFetchRequest error:nil]; // Don't be stupid like me and catch the error ;-)
[managerFetchRequest release];
if ([managers count] != 1)
// You probably have problems if this happens
[employee setValue:[managers objectAtIndex:0] forKey:@"manager"];
您也可以只执行一个提取请求,将所有管理器都放入importMoc
,然后过滤该数组以每次找到正确的。那可能会更有效率。换句话说,不要做我刚才告诉你的事情:-)
【讨论】:
所以阅读精美手册:如果我放弃你说要忽略的谓词并调用 [importMoc executeFetchRequest:error:] 我将得到一个数组,其中包含已保存到的所有管理器(例如)持久存储(无论其上下文如何)加上当前(importMoc)上下文中的任何管理器,无论它们是否已保存。我理解正确吗? 正确。上下文仅在对象在内存中时才重要。一旦它们被保存到持久存储中,就可以将它们提取到任何上下文中。 只是一个简短的说明,非常感谢亚历克斯的回答。我没有意识到如果 fetch 具有相同的持久存储协调器,它会将对象添加到单独的上下文中。我遇到了同样的问题,这个答案对我很有帮助!【参考方案2】:1/ 假设员工记录 X 的名称为 Y,部门 ID 为 15(即,它通过关系引用 ID 为 15 的部门)
2/ 从托管对象上下文中加载部门 id 为 15 的部门
3/ 创建一个引用在 (2) 处创建的对象的员工
即(注:仅示例代码,可能无法编译):
NSEntityDescription * departmentED = [NSEntityDescription entityForName:@"Department" inManagedObjectContext:moc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(id == %@)", deptId];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:departmentED];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
/* create employee */
NSEntityDescription * employeeED = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc];
NSManagedObject * employeeMO = [[[NSManagedObject alloc] initWithEntity:employeeED insertIntoManagedObjectContext:moc] autorelease];
/* set employee department to department instance loaded above */
[receiptObject setValue:[array objectAtIndex:0] forKey:@"department"];
【讨论】:
感谢 diciu,但这并不能回答我关于在两个不同上下文之间建立关系的最佳方法的问题(如核心数据编程指南 - 高效导入数据中所推荐的)。由于时间限制,我目前已停止使用第二个托管对象上下文进行导入,但我仍然很想知道正确的方法。我还发现了以下最近的问题,但提供的答案不是很令人满意:***.com/questions/1554623/…以上是关于在导入核心数据的同时建立关系?的主要内容,如果未能解决你的问题,请参考以下文章