核心数据迁移示例

Car*_*loS 2 core-data ios

我已经阅读了名为Core Data Model Versioning和Data Migration Programming Guide的文档.但我仍然没有得到很多这方面的技能.所以我想张贴一个我认识的例子.

我有两个实体RuleInstance. Rule有一个名为的属性identifier. Instance还有一个名为的属性identifier.

每个Rule都有一个唯一的标识符,每个实例都有一个identifier相同的标识符Rules.它就像是RuleInstance(它应该是)之间的许多关系.

在我的数据模型的新版本中,我想在Rule和之间建立多对多的关系Instance,我该如何进行迁移?

Car*_*loS 5

我已经明白了.首先,在创建持久性存储协调器时设置以下选项:

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

    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 

configuration:nil URL:storeURL options:options error:&error])
{
   //other code handle error
}
Run Code Online (Sandbox Code Playgroud)

使用Xcode创建映射模型,设置其源版本和目标版本.

创建一个NSEntityMigrationPolicy的子类,命名它MyPolicy,覆盖该方法.

-(BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)

调用此方法时,所有managedObject都已在目标上下文中创建,但它们的关系不是.在此方法中,检查dInstance是哪个实体,并为其建立关系.

使用Xcode,在映射模型中,将名为InstanceToInstance的映射策略的ENTITY MAPPINGS设置为MyPolicy.

每个Instance对象都会调用一次此方法.对于我的问题,我应该这样做:

-(BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error{
    NSError *superError = nil;
    BOOL mappingSuccess = [super createRelationshipsForDestinationInstance:dInstance entityMapping:mapping manager:manager error:&superError];
    if ([dInstance.entity.name isEqualToString:@"Rule"]){
        Instance *instance = (Instance*)dInstance;
        NSFetchRequest *fetch = [[NSFetchRequest alloc] initWithEntityName:@"Instance"];
        fetch.predicate = [NSPredicate predicateWithFormat:@"identifier == %@",instance.identifier];
        NSArray *result = [manager.destinationContext executeFetchRequest:fetch];
        Rule *rule = [result objectAtIndex:0];
        instance.rule = rule;
    }
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

然后,将在应用程序启动时创建规则和实例之间的关系.

另请注意,NSEntityMigrationPolicy的子类创建的关系不需要在xcode的迁移策略编辑窗口中设置值表达式,只需将其留空即可.