尝试在Core Data中执行大量迁移后保存数据 [英] Trying to save data after doing heavy weight migration in Core Data

查看:115
本文介绍了尝试在Core Data中执行大量迁移后保存数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个需要大量迁移的iOS应用程序。我做的是将我的旧数据模型中的类型为Integer64的实体的属性类型转换为新数据模型中的String类型。因为我正在改变属性的类型,这需要大量的迁移。现在,转换是工作正常,但不幸的是,我有麻烦保存新的实体后,它转换后,这就是为什么当我在迁移后启动我的应用程序,我无法查看使用输入的数据旧数据模型。这里是我使用的NSEntityMigrationPolicy的子类:

   - (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping :( NSEntityMapping *)映射管理器:(NSMigrationManager *)管理器错误:(NSError * __ autoreleasing *)错误{

NSManagedObject * newObject;
NSEntityDescription * sourceInstanceEntity = [sInstance entity];
NSManagedObjectContext * destMOC = [manager destinationContext];

//正确的实体?只是为了确保
if([[sourceInstanceEntity name] isEqualToString:@MyEntity]){
newObject = [NSEntityDescription insertNewObjectForEntityForName:@MyEntityinManagedObjectContext:destMOC];

//获取属性
NSDictionary * keyValDict = [sInstance committedValuesForKeys:nil];
NSDictionary * allAttributes = [[sInstance entity] attributesByName];

//在属性上循环
for(NSString * key in allAttributes){
//获取键和值
id value = [sInstance valueForKey:key] ;
if([key isEqualToString:@myAttribute]){
//这里检索旧值
NSNumber * oldValue = [keyValDict objectForKey:key];
//这里根据需要进行转换
NSString * newValue = [oldValue stringValue];
//然后存储新值
[newObject setValue:newValue forKey:key];
} else {
//不需要修改值,复制到
[newObject setValue:value forKey:key];

}

}

[manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
[destMOC save:error];
}

return YES;
}

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

return YES;
}

我试图尽可能彻底,也走过了迁移过程,但不幸的是,我不知道为什么我转换的实体没有保存在新的数据模型。我想指出一些可能是原因:



我正在转换/迁移的实体与4个其他实体有4个一对一的关系:一个关系具有逆,并且这些关系中的三个不具有逆。我知道有一个没有逆的关系是不推荐的,但这是如何设计原始的数据模型,不幸的是我没有什么能做的。但是,这些关系不会以任何方式从我的旧数据模型改变到新的数据模型。我的方法:

   - (BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping :( NSEntityMapping *)映射管理器: *)manager error:(NSError * __ autoreleasing *)error {

return YES;
}

现在必须更改以适应此,从而允许我保存我的数据,或者我可以单独使用这个方法,仍然保存数据我只是改变方法:

   - (BOOL) createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError * __ autoreleasing *)error {...} 

仍然保持现有的关系,因为它们是完整的?



我希望我的问题有意义。 >

感谢所有回复者。

解决方案

改变所有关系类型以在原始模型中具有逆关系,并且在新模型中保持相同的结构。当我使用上面的代码,一切都很好。



感谢所有考虑过这个问题的人。


I am working on an iOS application that requires heavy weight migration. What I am doing is converting the attribute type of an Entity in my old Data Model which is of type Integer64, to a type of String in the new Data Model. Because I am changing the type of the attribute, this requires heavy weight migration. Now, the conversion is working fine, but unfortunately I am having trouble saving the new Entity after it has been converted, which is why when I launch my application after doing the migration, I'm unable to view the data that was entered using the old Data Model. Here is the subclass of NSEntityMigrationPolicy that I am using:

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError *__autoreleasing *)error {

    NSManagedObject *newObject;
    NSEntityDescription *sourceInstanceEntity = [sInstance entity];
    NSManagedObjectContext *destMOC = [manager destinationContext];

    //correct entity?  just to be sure
    if ([[sourceInstanceEntity name] isEqualToString:@"MyEntity"]) {
        newObject = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:destMOC];

        //obtain the attributes
        NSDictionary *keyValDict = [sInstance committedValuesForKeys:nil];
        NSDictionary *allAttributes = [[sInstance entity] attributesByName];

        //loop over the attributes
        for (NSString *key in allAttributes) {
            //get key and value
            id value = [sInstance valueForKey:key];
            if ([key isEqualToString:@"myAttribute"]) {
                //here retrieve old value
                NSNumber *oldValue = [keyValDict objectForKey:key];
                //here do conversion as needed
                NSString *newValue = [oldValue stringValue];
                //then store new value
                [newObject setValue:newValue forKey:key];
            }  else {
                //no need to modify the value, Copy it across
                [newObject setValue:value forKey:key];

            }

        }

        [manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
        [destMOC save:error];
    }

    return YES;
}

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

    return YES;
}

I've tried to be as thorough as I can, and I've also stepped through the migration process, but unfortunately I can't figure out why the Entity that I'm converting is not being saved in the new Data Model. I do want to point out something that could possibly be the reason:

This entity that I am converting/migrating has 4 one-to-one relationships with 4 other entities: one relationship has an inverse, and three of these relationships do NOT have an inverse. I know having a relationship without an inverse is not recommended, but this is how the original Data Model was designed, and unfortunately there is nothing I can do about it. However, these relationships do NOT change in any way from my old Data Model to the new Data Model. Does my method:

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

        return YES;
    }

have to change now to accommodate this, and thus allowing me to save my data, or can I leave this method alone, and still save the data my simply making changes to the method:

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError *__autoreleasing *)error {...}

and still keep the existing relationships as they were intact?

I hope my question makes sense.

Thanks in advance to all who reply.

解决方案

I solved this problem by changing all of the relationship types to have inverse relationships in the original model, and kept this same structure in the new model. When I used my above code as is, everything worked fine.

Thanks to all who considered this problem.

这篇关于尝试在Core Data中执行大量迁移后保存数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆