将所有对象(保留它们的关系)从一个领域复制到另一个领域

Copying all objects (preserving their relationships) from one Realm to another

tl;dr:我试图将每个对象从一个领域复制到另一个领域,但我得到的对象数量是我应该的两倍或 4 倍(因为它们之间的关系) ,我想)。(编辑:我实际上得到了更多!检查我在底部的最后编辑。)

我试图让我的用户备份和恢复他们的 Realm 数据库。

我有一个Bookclass和一个ReadingSessionclass。一个Book可以有多个ReadingSessions:

class Book: Object {
    // (…)
    var readingSessions: [ReadingSession] {
        return linkingObjects(ReadingSession.self, forProperty: "book")
    }
}

class ReadingSession: Object {
    // (…)
    var book: Book?
}

要从备份恢复,我尝试这样做:

func restoreBackupFile(backupFileToRestore: String) {
    // (…) I omitted the NSFileManager related part.
    let config = Realm.Configuration(path: "\(tmp)/ReadingLog.realm", readOnly: true)
    let backupRealm = try! Realm(configuration: config)
    let defaultRealm = try! Realm()

    let results = backupRealm.objects(Book)

    try! defaultRealm.write {

        for result in results {
            defaultRealm.create(Book.self, value: result)
        }
    }

成功复制了所有 Book 对象,但没有复制与 Books 相关的 ReadingSessions。 所以我也添加了一些代码来复制每个 ReadingSession

    // (…)
    let bookResults = backupRealm.objects(Book)
    let sessionResults = backupRealm.objects(ReadingSession)

    try! defaultRealm.write {

        for result in bookResults {
            defaultRealm.create(Book.self, value: result)
        }
        for result in sessionResults {
            defaultRealm.create(ReadingSession.self, value: result)
        }
    }

这让我的 defaultRealm 书籍数量增加了 4 倍!我使用了一个包含 10 本书的数据库来测试它,在 运行 该代码之后,我的默认领域有 40 本书,其中 20 本书与 ReadingSessions 关联,20 本书没有任何 ReadingSessions全部.

我试着只复制 ReadingSessions 看看是否也会创建相关的 Books,然后我得到了两倍的 Books,其中一半是右边的ReadingSessions还有一半没有。

那么我怎样才能做我想做的事呢?将每个对象从一个领域复制到另一个领域,保持它们之间的关系完整,而不像我现在这样重复?

(我知道我可以只替换数据库文件,但我希望我的用户能够从一个数据库恢复数据而不会丢失另一个数据库的数据。)

提前致谢,

丹尼尔


编辑: 我一直在尝试更多,似乎如果我只复制 ReadingSessions 它会为每个复制的阅读会话创建一本书,即使他们与同一本书有关。例如,如果我有一本书有 60 次阅读,那么这本书将被创建 60 次。所以我的问题比我想象的还要严重。当我复制 Books 时,它们并没有附带相关的 ReadingSessions。当我复制 ReadingSessions 他们创建了许多重复的书。

当您在另一个领域的对象的基础上创建新对象时,链接的对象也会被复制并递归到其中。但是反向引用只是您对象上的便利吸气剂,模式既不知道也无法访问(对于 Swift),因此根本不会遍历它们。即使链接的对象被递归,它们也不会自动删除重复数据。所以这会 loop for circular relations.

您可能想要配置一个 primary key on Book and use create(… update: true) 来复制您的 ReadingSessions。当您复制两者时,您确保未读的书也被复制,如果这对您的架构有效的话。