应用升级后核心数据关系丢失

时间:2011-09-13 05:26:09

标签: iphone objective-c ios core-data core-data-migration

我有一个棘手的问题,我无法找到答案。我的数据模型结构如下:

版本1:
项目有很多地方
位置有很多项目
但错误的是,两者之间的反转从未设定过。

第2版:
与上面相同,但现在设置了逆。

我的问题的一个例子如下:
在版本1中,我有两个拥有相同位置的项目。当我启动版本2并处理我的映射模型时,拥有该位置的原始项目将失去与该位置的关系,现在该位置仅显示为其中一个项目的一部分,而不是两个项目。

我认识到这个问题可能是由于我没有在项目和位置之间建立反向关系造成的,但是我可以做些什么来使数据在应用程序/数据模型的两个版本中保持不变?

修改: 我尝试过推断的映射模型,我尝试手动创建映射模型。我目前仅在创建NSMigratePersistentStoresAutomaticallyOption时使用NSPersistentStoreCoordinator密钥。

另外,为了清楚起见,我有两个版本的数据模型,并且迁移成功发生,唯一的问题是关系不会按预期持续存在。

编辑2: 我已经发现我需要继承NSEntityMigrationPolicy。我不想进行完全自定义的迁移,如果可能的话,我宁愿自动保留其余的迁移。有没有人知道有关子类化NSEntityMigrationPolicy的任何好的教程或示例与我的目的相关?我找不到多少,据我所知,苹果文档中对它的引用极少。

编辑3: 我不能为我的生活弄清楚如何使用NSEntityMigrationPolicy建立反向关系。我现在的问题与我之前描述的有点不同。有谁知道如何做到这一点的任何可靠的例子?

4 个答案:

答案 0 :(得分:3)

不幸的。

您必须通过继承NSEntityMigrationPolicy手动进行迁移:(

阅读documentation here - 特别是关于自定义实体迁移政策的部分。

您必须自己创建反向关系作为迁移的一部分。

取值

答案 1 :(得分:1)

使用自动迁移模型设置持久性存储协调器,并查看是否有效。另外,你确实创建了一个新的模型版本,对吗?如果没有这两种模型,核心数据就无法映射。

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
     [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
     [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];


  NSError *error = nil;

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
  }

答案 2 :(得分:1)

您的第二个模型是否意外地将关系从“一对多”改变了?

如果是这样,您的迁移可能只会将一个位置分配给一个项目,因为它会从旧模型转换为新模型。

(这是猜测!)

答案 3 :(得分:0)

对于遇到这种情况的其他人来说,实际上有一个我没有考虑的非常简单的答案。

我试图继承NSEntityMigrationPolicy并没有太过分 - 我找不到任何超出基础知识的好示例代码。在某些情况下,子类化NSEntityMigrationPolicy可能是最佳解决方案。但是如果你和我的情况相同 - (意味着你已经在模型中设置了反向关系的正确字段,但是你忘了实际指定反转),我相信我有一个更简单的解决方案。

我没有对NSEntityMigrationPolicy进行子类化,而是执行了以下操作(这实际上是更简单的IMO):

(请记住,我的模型设置如下:项目< - >地点,已拥有和属于多人的关系)

  1. 我在我的应用中保留了旧的数据模型(.xcdatamodel)文件。当我的应用首次加载时,它会从旧数据模型文件中加载NSManagedObjectModel。然后我继续循环遍历我的数据库中的所有项目,并遍历每个项目的所有位置,并且对于每个位置,我将手动设置“项目”字段 - 如果我第一次设置了我的模型,这将使用反向关系自动完成。这是我的代码:

    NSArray *projects = [context executeFetchRequest:request error:&error];
    for(Project *project in projects) {
        for(Location *location in project.locations) {
            // set the inverse relationship manually
            [location addProjectsObject:project];
        }
    }
    
  2. 我保存了NSManagedObjectContext

  3. 然后我删除了NSManagedObjectContextNSManagedObjectModelNSPersistentStoreCoordinator并使用我的新xcdatamodel文件重建了它们。新模型文件包含反向关系,并且它们已正确设置。从SQLite数据库迁移数据时,所有数据都保持不变,并且我手动设置的反向关系仍然存在。创建新NSPersistentStoreCoordinator时,请务必指定NSMigratePersistentStoresAutomaticallyOption选项。