Миграция основных данных: выражение значения сопоставления атрибутов

В настоящее время у моего объекта есть атрибут cardType, который в старой модели мог быть «Математика», «Изображение» или «Текст». В новой модели я буду использовать только «Математика» и «Текст», а также иметь атрибут hasImage, для которого я хочу установить значение true, если старым типом карты было изображение (которое я хочу изменить на «Текст»).

Наконец, у меня есть набор другой сущности, «карты», набор которых может быть связан с колодой, и в каждой из них у меня также будет hasImage, для которого я хочу установить значение true, если колода была « Изображение" раньше.

Возможно ли все это с помощью выражения значения в модели сопоставления, которую я создал между двумя версиями, или мне придется сделать что-то еще?

Я не могу найти ни одного документа, в котором бы точно говорилось, что возможно в Value Expression (документ Apple — http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreDataVersioning/Articles/vmMappingOverview.html%23//apple_ref/doc/uid/TP40004735-SW3 — имеет очень простое преобразование). Если мне нужно сделать что-то еще, что это будет? Это кажется достаточно простым, чтобы выражение могло это сделать.


person Philippe Sabourin    schedule 20.03.2011    source источник


Ответы (1)


Одна вещь, которую вы можете сделать, — это создать собственный класс политики миграции, в котором есть функция, отображающая ваш атрибут из исходного значения в новое значение. Например, у меня был случай, когда мне нужно было сопоставить объект с именем MyItems, который имел прямое отношение к набору объектов значений, называемых Items, чтобы вместо этого хранить идентификатор itemID, чтобы я мог разделить модель на несколько хранилищ.

Старая модель выглядела так: старая модель

Новая модель выглядит так: новая модель

Для этого я написал класс сопоставления с функцией itemIDForItemName, и он был определен как таковой:

@interface Migration_Policy_v1tov2 : NSEntityMigrationPolicy {

  NSMutableDictionary *namesToIDs;
}

- (NSNumber *) itemIDForItemName:(NSString *)name;
@end

#import "Migration_Policy_v1tov2.h"

@implementation Migration_Policy_v1tov2


    - (BOOL)beginEntityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error {
        
        namesToIDs = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1],@"Apples",
                      [NSNumber numberWithInt:2],@"Bananas",
                      [NSNumber numberWithInt:3],@"Peaches",
                      [NSNumber numberWithInt:4],@"Pears",
                      [NSNumber numberWithInt:5],@"Beef",
                      [NSNumber numberWithInt:6],@"Chicken",
                      [NSNumber numberWithInt:7],@"Fish",
                      [NSNumber numberWithInt:8],@"Asparagus",
                      [NSNumber numberWithInt:9],@"Potato",
                      [NSNumber numberWithInt:10],@"Carrot",nil];
        return YES;
    }
    - (NSNumber *) itemIDForItemName:(NSString *)name {
        
        NSNumber *iD = [namesToIDs objectForKey:name];
        
        NSAssert(iD != nil,@"Error finding ID for item name:%@",name);
        
        return iD;
    }
    @end

Затем для связанного имени сопоставления для атрибута в вашей модели сопоставления вы указываете выражение значения как результат вызова вашей функции как такового: FUNCTION($entityPolicy,"itemIDForItemName:",$source.name) **

Вы также должны установить в поле пользовательской политики вашего имени сопоставления для этого атрибута имя вашего класса сопоставления (в данном случае Migration_Policy_v1tov2).

** обратите внимание, что это должно соответствовать сигнатуре селектора метода

Модель отображения

person Greg C    schedule 22.03.2011
comment
Это то, что я в итоге сделал - person Philippe Sabourin; 22.03.2011
comment
Спасибо за этот ответ! Ваш краткий пример сэкономил мне много времени и нервов. (Убьет ли Apple время от времени включение подобных вещей в свою документацию?) - person quickthyme; 30.07.2011
comment
@gregc Прежде всего, спасибо за интересный подход, которого я не нашел больше нигде. Это как раз то, что мне было нужно. Но, к сожалению, я не могу заставить его работать. Кажется, методы в моем пользовательском классе политики миграции не вызываются. В результирующей БД поля, которые должны быть заполнены значениями, возвращаемыми этими методами, пусты. Кроме того, я устанавливаю точки останова в этих методах, которые не срабатывают. Что можно сделать не так? Знаете ли вы какой-либо способ отладки процесса миграции (или хотя бы обеспечения его выполнения)? Спасибо! - person Mikayel Aghasyan; 28.03.2013
comment
изменился ли этот вид в xcode 4.62? Я не могу найти эти формы, где вы можете ввести пользовательскую политику - person roocell; 22.06.2013