复制整个对象图 - 复制关系

时间:2010-02-14 10:02:18

标签: iphone core-data copy entity-relationship

我有一个包含2个实体的模型:RealEstate和Container

容器对象已经保存到具有以下层次结构的持久性存储中:

Container 1
    Container 2
    Container 3
Container 4
    Container 5
        Container 6

每个容器都有一个RealEstate所有者(在给定的层次结构中,realEstate始终是相同的) 现在,我想为所有者realEstate的每个容器创建此层次结构的副本。 经过一些测试,在我看来,这不是一个小问题。

这是该模型的简化方案:

RealEstate (entity)
-------------------
name (string attribute)
containers (relation)

Container (entity)
------------------
level (int attribute)
name (string attribute)
parent (self relation to another container)
subcontainers (relation - set of containers)
realEstate (relation)

基本上每个容器都有与self的子容器关系,以及父关系等 容器1没有父级,但子容器= [容器2,容器3]等......

我有两个问题:

  • 如果我想要复制单个属性(NSNumber),我应该复制属性,然后再将其分配给复制的容器,例如[newContainer setLevel:[[container level] copy]],因为NSNumber实际上是一个指针,或者它是确定分配[newContainer setLevel:[container level]] ??
  • 如何复制关系?我不能简单地用[newContainer setSubcontainers:[container subcontainers]]复制子容器!!

这就是我正在做的事情:

- (void)copyContainersFromRealEstate:(RealEstate *)sourceRealEstate toRealEstate:(RealEstate *)destinationRealEstate {
    // read all RealEstate Containers to copy
 NSFetchRequest *request = [[NSFetchRequest alloc] init];
 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"realEstate == %@", sourceRealEstate];
 [request setPredicate:predicate];
 [request setEntity: [ NSEntityDescription entityForName:@"Container"
                 inManagedObjectContext:destinationRealEstate.managedObjectContext] ];

 NSError *error;
 NSArray *results = [destinationRealEstate.managedObjectContext executeFetchRequest:request 
                          error:&error];

 if (results == nil) {
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
 }
 [request release];

    // *******************************************************
 // copy each caontainer changing the real estate
 Container *newContainer;
 for (Container *container in results) {
      newContainer = (Container *)[NSEntityDescription insertNewObjectForEntityForName:@"Container" 
                 inManagedObjectContext:destinationRealEstate.managedObjectContext];

      [newContainer setRealEstate:destinationRealEstate];
      [newContainer setLevel:[container level]];
      [newContainer setSubcontainers:[container subcontainers]];  // WRONG
      [newContainer setName:[container name]];
      [newContainer setParent:[container parent]];  // WRONG
 }
    // *******************************************************

}

任何帮助将不胜感激。 感谢

2 个答案:

答案 0 :(得分:1)

  

如果我想复制单个属性(NSNumber),我应该复制属性,然后再将其分配给复制的容器,例如[newContainer setLevel:[[container level] copy]],因为NSNumber实际上是一个指针,或者它是确定分配[newContainer setLevel:[container level]] ??

将值设置到新对象上,它将处理它,即使它是一个指针,因为Core Data会将值写入数据库,因此它会在某个时刻将其转换为原语并“中断”您关心的指针关系。

  

如何复制关系?我不能简单地用[newContainer setSubcontainers:[container subcontainers]]复制子容器!!

只需设置对象,Core Data就会做正确的事情并正确构建新的关系。当您将NSSet传递给新的父对象时,Core Data将遍历集合中的对象,并为每个对象创建新的关系连接到新的父对象。

答案 1 :(得分:0)

感谢您的回复。 我很抱歉,如果写一个新的答案,但是发布截图的唯一方法。

  

只需设置对象,Core Data就会做正确的事情并正确构建新的关系。当您将NSSet传递给新的父对象时,Core Data将遍历集合中的对象,并为每个对象创建新的关系连接到新的父对象。

我理解coredata将创建与新父对象的新关系连接并自动进行必要的更改,特别是如果关系是在两个方向建模的,但在我的情况下出现问题,可能是因为我设计了我的关系。 查看我的代码我看到 [newContainer setParent:[container parent]]; 不是必需的,因为“parent”和“subcontainers”是反向关系,所以设置“subcontainers”会自动设置“parent”。但即使有这种变化,也有一些不妥之处。

为了简化问题,我刚做了这个测试:

  • 假设我只想复制一个子树而不是整个树,例如容器5及其子容器6(请参阅我的第一个答案中的层次结构)
  • 首先检查关系是否正确来源:如果我打印出sourceRealEstate容器5,我看到: Container5.parent = Container4,Container5.subcontainers = [Container 6] 。所以似乎一切都可以进入复制源
  • 比启动我的复制程序...之后我尝试以相同的方式打印出复制的对象,我看到: Container5.parent = nil(错),Container5.subcontainers = [容器6]( RIGHT)。比我重新检查源容器,我看到:*容器5.parent =容器4(右),Container5.subcontainer =空(错)

结论:子容器已移动而未复制

这是我的模型更详细:

http://www.freeimagehosting.net/uploads/9aae9b9ac8.png

Container.parent关系:
http://www.freeimagehosting.net/uploads/7f5c6592ef.png

Container.subcontainers关系:
http://www.freeimagehosting.net/uploads/bff3e1abe8.png