ios - CoreData 轻量级迁移崩溃,即使添加了映射模型
问题描述
在我的 CoreData 模型中,我创建了一个抽象实体 ( IDManagedObject
) 来为我的其他实体共享一个公共属性。
当我第一次运行它时,我遇到了几个Cannot merge multiple root entity source tables into one destination entity root table
错误。
完整的错误如下:
Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, reason=Cannot migrate store in-place: Cannot merge multiple root entity source tables into one destination entity root table, destinationURL=file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, NSUnderlyingError=0x6000019fb810 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={message=Cannot merge multiple root entity source tables into one destination entity root table, destinationRootEntity=IDManagedObject, NSUnderlyingException=Cannot merge multiple root entity source tables into one destination entity root table, sourceRootEntities=(
Book,
Author
), reason=Cannot merge multiple root entity source tables into one destination entity root table}}}, ["NSUnderlyingError": Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={message=Cannot merge multiple root entity source tables into one destination entity root table, destinationRootEntity=IDManagedObject, NSUnderlyingException=Cannot merge multiple root entity source tables into one destination entity root table, sourceRootEntities=(
Book,
Author
), reason=Cannot merge multiple root entity source tables into one destination entity root table}, "destinationURL": file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, "sourceURL": file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, "reason": Cannot migrate store in-place: Cannot merge multiple root entity source tables into one destination entity root table]: file MyApp/SceneDelegate.swift, line 96
有趣的是,它只显示了这两个实体的错误,但我还有更多。
经过一番搜索,我发现我需要添加一个映射模型来在新旧版本之间迁移。所以我通过 Xcode 中的 Cmd-N 添加它并选择源和目标模型。
但我仍然收到错误消息。
两者shouldMigrateStoreAutomatically
和shouldInferMappingModelAutomatically
都设置为true
。
我在这里想念什么?
旧模型在当前用 Objective-C 编写的应用程序中,新模型在用 Swift 编写的应用程序的新版本中,现在也使用CloudKit
. 使用 Xcode 12.2。
如果需要,我很乐意添加更多信息,只是不知道与该问题相关的内容。
解决方案
简短的版本是,即使使用映射模型,自动轻量级迁移也无法进行此更改。您需要进行完全手动迁移才能进行此更改。如果您查看 Apple 的轻量级迁移文档,它会说
...如果两个现有实体在源中不共享一个共同的父级,则它们不能在目标中共享一个共同的父级。
这是你想要做的,但它不能自动发生。
更长的答案为什么会涉及 Core Data 如何工作的一些细节。Xcode 并没有很好地说明这一点。
- 当您有两个或多个实体而没有共同的父实体时,Core Data 将它们视为完全独立的。你的 SQLite 有一个
Book
表,一个Author
表,等等。 - 当您有两个或多个实体具有共同的父级时,Core Data 将它们视为同一个表的特殊情况。你的 SQLite 有一个
IDManagedObject
表。Core Data 使用其他逻辑来决定该表中的条目是 aBook
还是 anAuthor
或其他东西。
因此,您实际上正在做的是将多个实体合并到一个新实体中。Core Data 不知道如何自动执行此操作,这就是它在该错误消息中告诉您的内容。
Core Data 只是抱怨这两个表,因为它们是它看到的第一个表。它无法处理合并它们中的任何一个,它只提到了两个表,因为它在查看其余表之前就放弃了。
要进行此更改,您需要创建一个迁移管理器并编写代码来进行迁移。Apple 在自定义迁移过程中对此进行了描述。或者,根据您的具体需要,可能还有其他解决方案不需要添加新的父实体。
推荐阅读
- c# - 来自角色的反应 C#
- javascript - 等待图像的格式更改
- c# - 来自 nugets 的跨平台项目和数据类
- javascript - [Vue警告]:
只能用于单个元素。利用 对于列表 - php - openpgp-php 无法解密来自其他客户端的密文
- web-services - 通过 web 服务登录 prestashop 1.7
- python - 在执行当前脚本之前运行 python 脚本
- c# - V5R4 上 iSeries 的 .NET 数据提供程序
- ios - 2 架构 arm64 的重复符号
- apache-kafka - Kafka Streams:处理来自不同分区的消息时的事件时间偏差