xcode 核心数据迁移:属性映射值表达

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5366587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 20:34:27  来源:igfitidea点击:

Core Data Migration: Attribute Mapping Value Expression

xcodeioscore-datamigrationmapping-model

提问by Philippe Sabourin

I currently have a cardType attribute on my entity, which in the old model could be "Math", "Image" or "Text". In the new model, I'll be using just "Math" and "Text" and also have a hasImage attribute, which I want to set to true if the old cardType was Image (which I want to change to "Text").

我目前在我的实体上有一个 cardType 属性,在旧模型中可能是“数学”、“图像”或“文本”。在新模型中,我将只使用“Math”和“Text”,并且还有一个 hasImage 属性,如果旧 cardType 是 Image(我想将其更改为“Text”),我想将其设置为 true。

Lastly, I have a set of another entity, "card", of which a set can be associated with a deck, and in each of those, I'll also have hasImage which I want to set to true if the deck was of "Image" type before.

最后,我有一组另一个实体,“卡片”,其中一组可以与一副牌相关联,并且在每一个中,我还将拥有 hasImage 如果牌组是“图像”类型之前。

Is this all possible using the Value Expression in the Mapping Model I've created between the two versions, or will I have to do something else?

这一切都可以使用我在两个版本之间创建的映射模型中的值表达式,还是我必须做其他事情?

I can't find any document telling me exactly what is possible in the Value Expression (Apple's doc - http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreDataVersioning/Articles/vmMappingOverview.html%23//apple_ref/doc/uid/TP40004735-SW3- only has a very simple transformation). If I have to do something else, what would that be? This seems simple enough that an expression should be able to do it.

我找不到任何文档告诉我值表达式到底有什么可能(Apple 的文档 - http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreDataVersioning/Articles/vmMappingOverview.html% 23//apple_ref/doc/uid/TP40004735-SW3- 只有一个非常简单的转换)。如果我必须做其他事情,那会是什么?这看起来很简单,表达式应该能够做到。

回答by Greg C

One thing you can do is create a custom migration policy class that has a function mapping your attribute from the original value to a new value. For example I had a case where I needed to map an entity called MyItems that had a direct relationship to a set of values entities called "Items" to instead store an itemID so I could split the model across multiple stores.

您可以做的一件事是创建一个自定义迁移策略类,该类具有将您的属性从原始值映射到新值的函数。例如,我有一个案例,我需要映射一个名为 MyItems 的实体,该实体与一组名为“Items”的值实体有直接关系,而不是存储一个 itemID,这样我就可以将模型拆分到多个商店。

The old model looked like this: old model

旧模型如下所示: 老款

The new model looks like this: new model

新模型如下所示: 新模式

To do this, I wrote a mapping class with a function called itemIDForItemName and it was defined as such:

为此,我编写了一个映射类,其中包含一个名为 itemIDForItemName 的函数,它的定义如下:

@interface Migration_Policy_v1tov2 : NSEntityMigrationPolicy {

  NSMutableDictionary *namesToIDs;
}

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


#import "Migration_Policy_v1tov2.h"

#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

Then for the related Mapping Name for the attribute in your mapping model you specify the Value Expression as the result of your function call as such: FUNCTION($entityPolicy,"itemIDForItemName",$source.name) . You also have to set the Custom Policy Field of your Mapping Name for that attribute to your mapping class name (in this case Migration_Policy_v1toV2).

然后,对于映射模型中属性的相关映射名称,您将值表达式指定为函数调用的结果: FUNCTION($entityPolicy,"itemIDForItemName",$source.name) 。您还必须将该属性的映射名称的自定义策略字段设置为映射类名称(在本例中为 Migration_Policy_v1toV2)。

Mapping Model

映射模型