核心数据迁移的例子

我读过名为“ 核心数据模型版本控制和数据迁移编程指南”的文档。 但是我仍然没有很多的技巧。 所以我想发表一个我遇到的例子。

我有两个实体RuleInstanceRule有一个名为identifier的属性。 Instance也有一个名为identifier的属性。

每个Rule都有一个唯一的标识符,每个实例的identifierRules一个相同。 这就像RuleInstance之间的很多关系(它应该是)。

在我的数据模型的新版本中,我想要在RuleInstance之间build立一对多关系,如何进行迁移?

我已经知道了。 首先,在创build持久性存储协调器时设置这些选项:

 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 } 

使用Xcode创build一个映射模型,设置它的源版本和目标版本。

创build一个NSEntityMigrationPolicy的子类,将其命名为MyPolicy ,覆盖该方法。

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

当这个方法被调用时,所有的managedObjects已经在目标上下文中创build,但是它们的关系不是。 在这个方法中,检查哪个实体是dInstance,并build立关系。

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

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

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

然后,应用程序启动时将创buildRule和Instance之间的关系。

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

看来您可以使用轻量级迁移来更改关系。

创build新版本后,只需更改或添加关系。

更多细节请看这里LightweightMigration

所有你需要做的是添加选项到你的委托中的persistentStoreCoordinator方法。

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (persistentStoreCoordinator != nil) { return persistentStoreCoordinator; } NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]]; // handle db upgrade 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 } return persistentStoreCoordinator; } 

然后,更改模型并select它作为活动后,只需重新安装您的应用程序。 就这样。