核心数据迁移 [英] core data migration by example

查看:136
本文介绍了核心数据迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了名为的文档核心数据模型版本化和数据迁移编程指南 。但我还是没有得到很多技能。



我有两个实体 Rule 实例
Rule 有一个名为 identifier 的属性。
实例也有一个名为 identifier 的属性。



每个规则都有一个唯一的标识符,每个实例都有标识符 Rules 。它像 Rule Instance (应该是)之间的许多关系。



在我的数据模型的新版本中,我想在 Rule Instance ,我如何做迁移?

解决方案


首先,创建持久存储协调器时设置这些选项:

  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])
{
/ /其他代码句柄错误
}

使用Xcode创建映射模型,和目标版本。



创建NSEntityMigrationPolicy的子类,将其命名为 MyPolicy ,覆盖该方法。 (NSMigrationManager *)管理器错误:(NSMigrationManager *)管理器错误:(NSMigrationManager *)管理器错误:(NSMigrationManager *)管理器错误:(NSMigrationManager * *)错误

当调用此方法时,所有managedObject都已在目标上下文中创建,关系不是。
在此方法中,检查什么实体是dInstance,并为它建立关系。



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



将为每个实例对象调用一次。
我的问题,我应该这样做:

   - (BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping: (NSEntityMapping *)映射管理器:(NSMigrationManager *)管理器错误:(NSError **)错误{
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;
}

然后,应用程式启动时会建立Rule和Instance 。



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


I've read the document named Core Data Model Versioning and Data Migration Programming Guide. But I still don't get many skills on this. So I want to post an example I met.

I have two entities Rule and Instance. Rule has an attribute named identifier. Instance also has an attribute named identifier.

every Rule has an unique identifier and every instance have an identifier the same to one of Rules. It is like a to many relationship between Rule and Instance (and it should be).

In new version of my data model, I want to make a to-many relationship between Rule and Instance, how do I do the migration?

解决方案

I've figured it out. first, set these options when creating persistent store coordinator:

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
}

Create a mapping model with Xcode, setting its source version and destination version.

Make a subclass of NSEntityMigrationPolicy,name it MyPolicy, overwrite the method.

-(BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error

when this method is invoked, all the managedObjects has been create in destination context, but their relationships are not. In this method, check what entity is the dInstance, and make relation for it.

With Xcode,in your mapping model, set The ENTITY MAPPINGS named InstanceToInstance's mapping policy to MyPolicy.

this method will be called once for each Instance object. for my question, I should do this:

-(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;
}

Then, the relation ship between Rule and Instance will be created when the app launches.

Also notice, relationships created by subclass of NSEntityMigrationPolicy don't need to set the value expression in xcode's migration policy editing window, just leave it blank.

这篇关于核心数据迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆