0

我有一个管理 10 个不同实体的核心数据应用程序。它们基本上都是相同的,并且具有相同的属性。(NSStrings 和 UIImage)这会产生一个包含 10 个表的 sqlite DB:

Collection A table
-item with attributes xyz
-item with attributes xyz
-item with attributes xyz
Collection B table
-item with attributes xyz
-item with attributes xyz
-item with attributes xyz
etc, etc

我现在意识到这是一个不好的方法。我最终得到了 10 个不同的视图控制器和 10 个不同的 FRC。我应该把所有东西都放在一个带有“collectionX”属性的表中。这样,我将所有集合项都放在一个表下,并且根据用户所在的集合,我可以使用“collectionX”属性从 FRC 中返回这些项目,并带有谓词。

我想做的是将所有内容迁移到一个表中并为集合名称添加一个属性:

Collection table
-item from collection A (w/new "collectionX" attribute filled in as "collectionA")
-item from collection A (w/new "collectionX" attribute filled in as "collectionA")
-item from collection A (w/new "collectionX" attribute filled in as "collectionA")
-item from collection B (w/new "collectionX" attribute filled in as "collectionB")
-item from collection B (w/new "collectionX" attribute filled in as "collectionB")
-item from collection B (w/new "collectionX" attribute filled in as "collectionB")
etc, etc

因此,通过轻量级迁移,我应该能够进入所有 10 个实体并添加新的“collectionX”属性并使用关联集合的字符串填充它。

现在是困难的部分......我现在如何获取每个表中的所有条目并将它们全部复制到一个新表中并删除旧的 10 个表?

4

1 回答 1

2

如果我从 N 个数据库迁移到单个数据库,我什至不知道我会迈出第一步。

相反,在应用程序启动时,我会寻找“新”数据库。如果它不存在,那么我会寻找其他数据库,然后启动后台更新。

在该后台线程中,为新数据库创建一个完整的核心数据堆栈,然后遍历每个旧数据库。使用线程限制创建所有 MOC,以便更轻松地使用线程。

对于每个“旧”数据库,查询所有对象,然后遍历每个对象,将其值分配给新数据库中新插入的对象。

如果您的所有实体都具有相同的名称,那就小菜一碟。如果没有,那么您可以从 NSEntityDescription 中获取属性名称,然后遍历属性。使用 KVC(即,valueForKey:使setValue:forKey:为新对象设置适当的值变得容易。然后,分配适当的类别。

完成所有对象的循环后,您现在在“新”数据库中有重复的数据库,因此您可以删除旧的。关闭“新”数据库,然后通过正常的初始化阶段来创建所使用的数据库

如果您有大量数据,并希望应用程序在迁移时正常运行,您甚至可以让应用程序在后台执行更新时使用旧数据文件运行。更新完成后,您可以进行交换。

编辑

“循环遍历每个旧数据库”是什么意思?如何有效地“剪切和粘贴”所有这些数据?– 黑麦MAC3

正是这样。遍历 10 个数据库中的每一个。就像是:

for (NSString *dbName in databaseNames) {
    // Create a Core Data stack for the old database
    NSManagedObjectContext *oldDatabaseMOC = ...
    // Now, fetch objects from that database and insert new ones into the new database
}
于 2012-09-17T14:23:44.383 回答