核心数据迁移“无法将模型与名为'foo'的两个不同实体合并”

时间:2010-09-22 21:54:51

标签: iphone core-data migration

我知道这是一个经常被问到的问题,但是我找到的解决方案似乎都不适用于我。

这是我的情况: 我的应用程序有一个数据模型,我想为它添加版本。所以在XCode中,我做了Design - >数据模型 - >添加模型版本。我还更新了我的委托的persistentStoreCoordinator方法,如下所示:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
                                               stringByAppendingPathComponent: @"foo.sqlite"]];

    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]) {
        /*Error for store creation should be handled in here*/
    }

    return persistentStoreCoordinator;
}

为了确保一切仍然有效,我做了一个干净的所有,构建,并在模拟器中测试它。一切都运作到目前为止。

接下来,我选择了新版本数据模型,使用XCode将其设置为当前版本,并为实体添加了一个额外属性。然后,我做了一个干净的所有,构建。现在,每当我启动应用程序时,它都会崩溃并出现此错误:'无法将模型与名为'foo''的两个不同实体合并。

我做错了什么?我已经尝试确保没有向目标添加数据模型,只将当前版本数据模型添加到目标,以及两者。每次我测试我都要确保清理所有。

任何人都可以解释为什么它对我不起作用?

编辑:

这是我的managedObjectModel方法:

- (NSManagedObjectModel *)managedObjectModel {
  if (managedObjectModel != nil) {
    return managedObjectModel;
  }
  managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

  return managedObjectModel;
}

2 个答案:

答案 0 :(得分:5)

我已经预料到了managedObjectModel getter的这种实现。

在您的实现中,捆绑包中的所有模型都合并为一个模型。因此,.momd中的所有版本也会合并,从而导致重复的实体定义。

更改代码以使用适当的模型文件显式初始化模型,它应该可以正常工作。

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"datamodel" ofType:@"momd"];
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    

答案 1 :(得分:0)

如果您在核心数据上使用Version Models,则必须初始化为您要使用的版本的版本。在Application Bundle上,您会找到一个扩展名为.momd的文件,即完整模型。在此文件中,您会在其中找到大量.mom个文件,每个.mom文件代表您模型的一个版本

如果您运行应用程序并使用.momd文件及其中的所有版本进行初始化,Core Data将创建所有版本,之后我们将拥有 “重复实体” 错误,Core Data不知道使用什么版本。现在,解决问题的唯一方法是删除应用程序,将代码指向正确的.mom文件并再次运行,因此Core Data只创建一个内部数据库版本。

以下是执行此任务的一段代码:

NSString *fullModelName    = @"myModel.momd";    // The name of the main model.
NSString *modelVersionName = @"myModel1.0.mom";  // Only the name of the version.
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *modelPath = [NSString stringWithFormat:@"%@/%@/%@", bundlePath, fullModelName,  modelVersionName];
//
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];