2

Core Data Model Versioning and Data Migration Programming Guideという名前のドキュメントを読みました。しかし、私はまだこれについて多くのスキルを身につけていません。そこで、私が出会った例を投稿したいと思います。

と の 2 つのエンティティがRuleありInstanceます。 Ruleという名前の属性がありますidentifierInstanceという名前の属性もありますidentifier

everyRuleには一意の識別子があり、すべてのインスタンスには のidentifier1 つと同じものがありRulesます。Ruleこれは、との間の多対多の関係のようなものですInstance(そうあるべきです)。

Ruleデータ モデルの新しいバージョンで、 と の間に対多関係を作成したいのですInstanceが、移行を行うにはどうすればよいですか?

4

2 に答える 2

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
}

ソース バージョンと宛先バージョンを設定して、Xcode でマッピング モデルを作成します。

NSEntityMigrationPolicy のサブクラスを作成し、名前を付けてMyPolicy、メソッドを上書きします。

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

このメソッドが呼び出されると、すべての managedObjects が宛先コンテキストで作成されていますが、それらの関係は作成されていません。このメソッドでは、dInstance がどのエンティティであるかを確認し、関連付けを行います。

Xcode を使用して、マッピング モデルで、ENTITY MAPPINGS namedInstanceToInstanceのマッピング ポリシーを に設定しMyPolicyます。

このメソッドは、インスタンス オブジェクトごとに 1 回呼び出されます。私の質問では、これを行う必要があります:

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

次に、アプリの起動時にルールとインスタンスの関係が作成されます。

また、NSEntityMigrationPolicy のサブクラスによって作成された関係は、xcode の移行ポリシー編集ウィンドウで値式を設定する必要はなく、空白のままにしておく必要があることに注意してください。

于 2012-12-26T06:51:52.857 に答える
3

関係変更には軽量マイグレーションが使えそうです。

新しいバージョンを作成したら、関係を変更または追加するだけです。

詳細については、こちらを参照してください

デリゲートの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;
}

次に、モデルを変更してアクティブとして選択した後、アプリを再インストールするだけです。それで全部です。

于 2012-12-17T09:12:46.053 に答える