【问题标题】:property mapping not being associated correctly. Why?属性映射未正确关联。为什么?
【发布时间】:2014-10-10 19:54:44
【问题描述】:

编辑 1 虽然我知道对于这种特殊情况(和其他类似情况),我可以单独使用映射编辑器来正确迁移我的存储,以便持久存储中的值不会跳来跳去,但这不是我当前问题的解决方案,而只是避免解决问题的根源。我热衷于坚持我的自定义迁移策略,因为这将使我在迁移过程中获得很多控制权,特别是对于未来设置自定义迁移策略对我有用的场景。这是一个长期的解决方案,而不仅仅是针对这种情况。

我敦促您尝试帮助我解决当前的情况,而不是让我转向轻量级迁移或建议我避免使用迁移策略。谢谢。

我真的很期待解决这个问题以及您对我可以做些什么来解决这个问题的宝贵意见/想法。

我做了什么: 我设置了迁移策略,以便可以将源数据从核心模型的version 1 复制到目标数据到version 2。

这是迁移政策:

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error {
    
    // Create the product managed object 
    NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName]
                                                               inManagedObjectContext:[manager destinationContext]];
    
    NSString *productCode = [sInstance valueForKey:@"productCode"];
    NSNumber *productPrice = [sInstance valueForKey:@"productPrice"];
    
    [newObject setValue:productCode forKey:@"productCode"];
    [newObject setValue:productPrice forKey:@"productPrice"];
    
    //This is the field where the name has changed as well as the type.
    [newObject setValue:[NSNumber numberWithBool:YES] forKey:@"productPriceNeedsUpdating"];

    // Set up the association between the old source product and the new destination Product for the migration manager
    [manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];


    /* 
  A test statement to make sure the destination object contains the correct
    values int he right properties:

    Product description: <NSManagedObject: 0xb983780> (entity: Product; id: 0xb9837b0 <x-coredata:///Product/t97685A9D-09B4-475F-BDE3-BC9176454AEF6> ; data: {
        productCode = 9999;
        productPrice = "2.09";
        productPriceNeedsUpdating = 1;
    })
    */

    
    // Set up the association between the old source product and the new destination Product for the migration manager

    return YES;
}

因此,即使测试的属性在运行时显示正确的值,保存在数据模型存储中的结果值也不正确,如快照所示。

这是数据存储版本 1 与版本 2 的比较。

版本 1:正确

到版本 2:现在错误地存储了值。

预期的输出应该将 Product price 插入到 productPrice 字段中,而不是在实际上应该只有布尔值的 ProductPriceNeedsUpdating 字段中。 谁能帮我理解我做错了什么,或者解释一下这里发生了什么?

更新 1 - 这是我的entity mappings:

更新 2 - 2014 年 8 月 20 日 01:02 GMT

当我从版本 1 中删除 date 类型的属性 ProductPriceLastUpdated 并在版本 2 中删除 boolean 类型的属性 ProductPriceNeedsUpdate 时,只留下在版本 1 和 2 中都匹配的两个属性,然后一切正常。即使我可以把它留在这里继续前进,我也不能忽略当前正在使用数据库版本 1 的用户,这些用户确实具有无意义的 ProductPriceLastUpdated 属性,我需要将类型转换为布尔值并且名称也更改为 @ 987654337@。那是事情开始变得奇怪的时候,价格值显示在ProductPriceNeedsUpdate 字段而不是productPrice 字段中。

我希望有人可以解决最初的问题并告诉我为什么实体映射,或者更多,属性映射没有被正确保存?

更新 3 - EntityMapping 和属性:

版本 1

第 2 版

有什么想法吗?

【问题讨论】:

  • 您尝试过轻量级迁移吗?我还没有观看整个视频,但乍一看您的更改可能适合。 (Core Data 能够生成推断映射模型,更改必须符合明显的迁移模式,例如:简单添加新属性 删除属性)
  • 如果您可以尝试在此处更详细地描述您的问题,而不是链接到 Dropbox 上的视频,这将对其他用户有所帮助。
  • @TimurKuchkarov 轻量级迁移不适合我的需求,因为我将对核心数据模型进行更多更改。我需要知道如何让 xcode 读取映射模型并将持久存储更新为最新模型。我相信这个过程被称为progressive migration。

标签: ios objective-c core-data ios7 core-data-migration


【解决方案1】:

首先,如果您只想使用轻量级迁移(在这种情况下确实应该这样做),您可以摆脱自定义迁移策略。在这种情况下,它是不需要的。而且,事实上,您也可以摆脱自定义映射模型。您需要做的就是在您的版本 2 模型中,选择 productPriceNeedsUpdating 布尔标志,然后在右侧的属性详细信息检查器中,将默认值设置为 YES。这将实现您尝试通过自定义迁移策略实现的目标。

但是,如果您确实需要使用自定义迁移策略在代码中编写此代码,我仍然不会使用自定义代码。您可以仅使用映射模型来实现此迁移。只需选择 ProductToProduct 映射,然后在 productNeedsUpdating 的值表达式中输入 YES 或 1。

编辑

因此,在相当长的屏幕共享之后,确定迁移使用的是 Marcus Zarra 的核心数据书中描述逐步迁移商店的代码。编写此代码时,WAL 模式不是 Core Data 的默认模式。启用 WAL 模式后,渐进式迁移存储无法正常运行,因为还有两个文件要处理,即预写日志和共享内存文件。当简单地用新存储替换旧存储时,没有先删除这些文件,就会发生奇怪的事情,如本文所述。最终解决方案是为渐进式迁移场景禁用 WAL 模式,这样一开始就不会生成额外的文件。

【讨论】:

  • 您好,感谢您的发帖。我相信您已经错过了赏金附带的说明。我不打算进行轻量级迁移,因为将来我将进行大量重度迁移。想想whatsapp,例如在新功能更新之后,每次修订都会发生巨大的商店模型变化。这只是一个微不足道的例子,我这​​样做只是为了在我确实需要进行自定义重迁移时热身。如果你能理解我写的问题,然后写一个与问题相关的回复以及我如何解决它,那将不胜感激!
  • 我无法弄清楚是什么导致这些值出现在错误的字段中,这真是太烦人了。我理解你为什么说在这种情况下可以使用轻迁移 - 但是我真的希望通过自定义重迁移来弄脏我的手,并且已经让这一切都很好地工作,唯一的例外是我不明白为什么要插入这些值进入错误的字段/列,以及为什么另一列显示为零。布尔字段应该是yes,而价格应该是价格值。在这种情况下,产品代码是正确的 - 是一个 4 位数字。
  • 有什么想法吗?
  • 您是否查看过您的映射模型并仔细检查过您是否以某种方式跨越了那里的字段?为什么不尝试搁置您当前的映射模型,并从步骤 1 开始重新尝试。有时当我犯了一个简单的错误但我找不到它时,我需要这样做。无需删除当前模型,只需将其从构建目标中删除,然后重新开始
  • 你是怎么做到的?这不会改变修订版 1 的核心数据模型的哈希标签,从而无法顺利过渡,还是不是这样?目标是确保应用程序中的当前版本 1 可以迁移到版本 2(我能够做到),但值在错误的字段中除外。我已经交叉检查了所有内容!跨度>
猜你喜欢
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 2020-01-06
  • 1970-01-01
相关资源
最近更新 更多