【问题标题】:Core Data migration "can't merge models with two different entities named 'foo'"核心数据迁移“无法将模型与名为 'foo' 的两个不同实体合并”
【发布时间】:2010-09-22 21:54:50
【问题描述】:

我知道这是一个常见问题,但我发现的解决方案似乎都不适合我。

这是我的情况: 我的应用程序有一个数据模型,我想向它添加版本控制。所以在 XCode 中,我做了设计 -> 数据模型 -> 添加模型版本。我还更新了我的委托的 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;
}

【问题讨论】:

  • 请添加您的 -(NSManagedObjectModel*) managedObjectModel 方法。我怀疑那里的问题。

标签: iphone core-data migration


【解决方案1】:

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

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

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

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

【讨论】:

  • 这样做,我得到一个不同的错误:“这个 NSPersistentStoreCoordinator 没有持久存储。它不能执行保存操作。”
  • 记录 modelPath 以查看您是否确实加载了有效的托管对象模型。
  • 我最终没有使用自动推断映射模型的选项,而是定义了我自己的。现在一切都按预期工作。谢谢。我记录了 NSPersistentStoreCoordinator 的错误,它说无法推断映射模型。
【解决方案2】:

如果您在 Core Data 上使用 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]; 

【讨论】:

  • NSString *modelPath = [NSString stringWithFormat:@"%@/Contents/Resources/%@/%@", bundlePath, fullModelName, modelVersionName];
猜你喜欢
  • 2011-03-13
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多