Связь основных данных потеряна после обновления приложения

У меня сложный вопрос, на который я не могу найти ответ. Моя модель данных устроена следующим образом:

Версия 1:
проект имеет много местоположений
расположение имеет много проектов
Но по ошибке обратное значение между ними никогда не устанавливалось.

Версия 2:
То же, что и выше, но теперь настроено обратное.

Вот пример моей проблемы:
В версии 1 у меня есть два проекта, которые владеют одним и тем же местоположением. Когда я запускаю версию 2 и моя модель сопоставления обрабатывается, исходный проект, владеющий местоположением, теряет связь с этим местоположением, и теперь местоположение отображается только как часть одного из проектов, а не обоих.

Я понимаю, что эта проблема, вероятно, вызвана тем, что я не настроил обратную связь между проектами и местоположениями, но могу ли я что-нибудь сделать, чтобы данные сохранялись в двух версиях модели приложения/данных?

Редактировать: я попробовал использовать предполагаемую модель сопоставления и попытался создать модель сопоставления вручную. В настоящее время я использую только ключ NSMigratePersistentStoresAutomaticallyOption, когда создавал свой NSPersistentStoreCoordinator.

Кроме того, просто для ясности: у меня есть две версии моей модели данных, и миграция выполняется успешно, единственная проблема заключается в том, что отношения не сохраняются должным образом.

Редактировать 2: я понял, что мне нужно создать подкласс NSEntityMigrationPolicy. Я не хочу выполнять полностью пользовательскую миграцию, я бы предпочел, чтобы остальная часть моей миграции была автоматической, если это возможно. Кто-нибудь знает какие-либо хорошие учебные пособия или примеры по созданию подклассов NSEntityMigrationPolicy, которые будут иметь отношение к моей цели? Мне не удалось найти многого, и, насколько я могу судить, в документах Apple очень мало упоминаний об этом.

Изменить 3: я не могу понять, как настроить обратную связь с помощью NSEntityMigrationPolicy. Моя проблема немного отличается от того, что я описал ранее. Кто-нибудь знает какой-нибудь надежный пример того, как это сделать?


person Michael Frederick    schedule 13.09.2011    source источник
comment
моя модель сопоставления обработана -› поместите сюда код, который сопоставляет две ваши модели.   -  person Nekto    schedule 13.09.2011


Ответы (4)


Несчастливый.

Вам придется выполнить миграцию вручную, создав подкласс NSEntityMigrationPolicy :(

Ознакомьтесь с документация здесь — в частности, раздел о политиках переноса настраиваемых объектов.

Вам нужно будет создать обратное отношение самостоятельно как часть миграции.

S

person deanWombourne    schedule 16.09.2011
comment
Да, я читал это в документации сегодня утром, но на самом деле я не нашел хорошего примера того, как это сделать. Я не хочу вручную переносить все, я считаю, что могу просто перенести определенные объекты. - person Michael Frederick; 16.09.2011

Настройте координатора постоянного хранилища, используя модель автоматической миграции, и посмотрите, работает ли это. Кроме того, вы создали новую версию модели, верно? Core Data не может сопоставить без обеих моделей.

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
  }
person Kendall Helmstetter Gelner    schedule 13.09.2011
comment
Да, я установил новую версию модели. Обновление прошло успешно, но связь потеряна. Я попробую автоматическую миграцию, спасибо за совет. - person Michael Frederick; 13.09.2011
comment
Не повезло с моделью предполагаемого отображения, она дает те же результаты, что и модель отображения, которую я создал вручную (что имеет смысл — кажется, что модель предполагаемого отображения просто перебирает разные модели в вашем комплекте, пока не найдет подходящую пару) . - person Michael Frederick; 13.09.2011

Ваша вторая модель случайно изменила отношение с «один ко многим»?

Если это так, ваша миграция может назначить местоположение только одному проекту, поскольку он преобразует старую модель в новую.

(Это предположение!)

person deanWombourne    schedule 16.09.2011

Для всех, кто сталкивается с этой ситуацией, на самом деле был очень простой ответ, который я не рассматривал.

Я не зашел слишком далеко, пытаясь создать подкласс NSEntityMigrationPolicy — я не смог найти ни одного хорошего примера кода, выходящего за рамки основ. В определенных ситуациях создание подкласса NSEntityMigrationPolicy может быть лучшим решением. Но если вы находитесь в той же ситуации, что и я (это означает, что вы настроили правильные поля для обратных отношений в своей модели, но забыли указать обратные отношения), я полагаю, что у меня есть более простое решение.

Вместо подкласса NSEntityMigrationPolicy я сделал следующее (что на самом деле намного проще IMO):

(имейте в виду, что моя модель настроена следующим образом: Проекты ‹--> Местоположения, отношение «имеет и принадлежит ко многим»)

  1. Я сохранил файл своей старой модели данных (.xcdatamodel) в своем приложении. Когда мое приложение загружается впервые, оно загружает мой NSManagedObjectModel из файла старой модели данных. Затем я перебрал все проекты в моей базе данных и все местоположения для каждого проекта, и для каждого местоположения я бы вручную установил поле «проект» - если бы я правильно настроил свою модель в первый раз. , это было бы выполнено автоматически с использованием обратных отношений. Вот как выглядит мой код:

    NSArray *projects = [context executeFetchRequest:request error:&error];
    for(Project *project in projects) {
        for(Location *location in project.locations) {
            // set the inverse relationship manually
            [location addProjectsObject:project];
        }
    }
    
  2. Я сохранил свой NSManagedObjectContext.

  3. Затем я избавился от своих NSManagedObjectContext, NSManagedObjectModel, NSPersistentStoreCoordinator и перестроил их, используя новый файл xcdatamodel. Новый файл модели содержит обратные отношения, и они настроены правильно. При переносе данных из базы данных SQLite все данные сохранились, и обратные отношения, которые я установил вручную, остались на месте. При создании нового NSPersistentStoreCoordinator обязательно укажите параметр NSMigratePersistentStoresAutomaticallyOption.

person Michael Frederick    schedule 31.05.2012