我正在尝试使用 xcode (.xcdatamodel) 创建的数据模型和运行时以编程方式创建的映射模型手动调用 CoreData 迁移。 迁移似乎已完成且没有错误,但新创建的数据库中没有数据。数据库的结构在那里(表、Z_METADATA 等),但数据没有结转,显然我的 NSMappingModel 没有被应用。
迁移总结:Country 实体已重命名为 Country2,Country.name 已重命名为 Country2.new_name。
NSMutableArray *attrMaps = [[NSMutableArray alloc] init];
NSPropertyMapping *pMap = [[NSPropertyMapping alloc] init];
pMap.name = @"new_name";
pMap.valueExpression = [NSExpression expressionForKeyPath:@"source.name"];
[attrMaps addObject:pMap];
NSEntityMapping *eMap = [[NSEntityMapping alloc] init];
eMap.sourceEntityName = @"Country";
eMap.destinationEntityName = @"Country2";
eMap.name = @"CountryToCountry2";
eMap.mappingType = NSTransformEntityMappingType;
eMap.attributeMappings = attrMaps;
NSMutableArray *eMaps = [[NSMutableArray alloc] init];
[eMaps addObject:eMap];
NSMappingModel *mappingModel = [[NSMappingModel alloc] init];
mappingModel.entityMappings = eMaps;
NSURL * storeURL = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@/Documents/%@",NSHomeDirectory(),@"TestCoreData.sqlite"]];
NSURL * storeURL2 = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@/Documents/%@",NSHomeDirectory(),@"TestCoreData2.sqlite"]];
NSMigrationManager *migman = [self getMigrationManager];
NSError * err;
BOOL ok = [migman migrateStoreFromURL:storeURL
type:NSSQLiteStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:storeURL2
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:&err];
更多信息
将我手工制作的 NSMappingModel 与在 XCode 的 GUI 中创建的模型进行比较,您可以看到一些差异:
来自 Xcode 的 GUI
entityMappings (
"(NSEntityMapping),
name CountryToCountry2,
mappingType 5,
sourceEntityName Country,
sourceEntityVersionHash <828c33cf 3ffdc5df dd1e73e8 4f7b60a5 f10dcb43 af26adeb 33d2c518 0c992dd8>,
destinationEntityName Country2,
destinationEntityVersionHash <8cdb8ecf cb47b39d 4b45858f a247487a dd88088b f509a6ec cc938740 5cf7a041>, attributeMappings (
"(NSPropertyMapping), name new_name, valueExpression $source.name, userInfo (null)"
), relationshipMappings (
), sourceExpression FETCH(FUNCTION($manager, "fetchRequestForSourceEntityNamed:predicateString:" , "Country", "TRUEPREDICATE"), $manager.sourceContext, NO),
entityMigrationPolicyClassName (null), userInfo (null)"
我的
entityMappings (
"(NSEntityMapping),
name CountryToCountry2,
mappingType 5,
sourceEntityName Country,
sourceEntityVersionHash (null),
destinationEntityName Country2,
destinationEntityVersionHash (null),
attributeMappings (
"(NSPropertyMapping), name new_name, valueExpression source.name, userInfo (null)",
), relationshipMappings (
), sourceExpression (null),
entityMigrationPolicyClassName (null), userInfo (null)"
更新
我已将此 sourceExpression 添加到我的实体映射中,现在 Country 的行已复制到新数据库,但它们是空的。所以 NSPropertyMappings 似乎仍然没有生效:
eMap.sourceExpression = [NSExpression expressionWithFormat:@"FETCH(FUNCTION($manager, \"fetchRequestForSourceEntityNamed:predicateString:\" , \"Country\", \"TRUEPREDICATE\"), $manager.sourceContext, NO)"];
最佳答案
NSPropertyMapping 的 valueExpression 定义不正确。它应该是 expressionWithFormat:
而不是 expressionForKeyPath:
和 $source
而不是 source
。像这样:
pMap.valueExpression = [NSExpression expressionWithFormat:@"$source.name"];
这样,我就有了一个实际工作的手工制作的 NSMappingModel。
关于ios - CoreData 自定义 NSMappingModel 不迁移数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33381702/