在Realm Swift中从一对一关系转变为一对多关系

时间:2016-02-04 10:43:00

标签: ios swift realm

我正在使用Swift 2.1.1RealmSwift 0.97.1构建Swift iOS应用。我的初始要求涉及类AB之间的一对一关系,所以我写了以下内容:

class A: Object {
    dynamic var b: B? // A has one B
}

class B: Object {
    var a: A {
        return linkingObjects(A.self, forProperty: "b")[0]
    }
}

这很好用,但现在我的要求发生了变化,我需要一对多的关系:

class A: Object {
    var bs: [B] {
        return linkingObjects(B.self, forProperty: "a")
    }
}

class B: Object {
    dynamic var a: A? // B belongs to A
}

我拥有真实数据的用户,因此我真的希望使用迁移优雅地推出此更改。

根据我的尝试,我无法在迁移中更改关系(我得到Can not add objects from a different Realm)。实际情况如此吗?

作为一种解决方法,我创建了一个将主键映射到B主键的字典。这也意味着我必须向B添加一个以前没有的主键。然后,在迁移之外,我改变了关系的顺序:

for (aKey, bKey) in keyMap {
    let a = realm.objectForPrimaryKey(A.self, key: aKey)
    let b = realm.objectForPrimaryKey(B.self, key: bKey)

    b?.a = a
    a?.b = nil
}

这样可行,但我似乎无法摆脱A的{​​{1}}财产。如果我尝试删除它,构建字典的迁移部分将失败:如果我使用b并且没有主键,则AB之间没有链接如果我使用newObject,则B。如果我可以对更新进行排序(首先添加主键,然后构建字典,然后删除oldObject属性),这一切都可以正常工作,但我不认为这是可能的。

有没有更好的方法来实现这一变化?如果没有,有没有办法可以删除b属性?

1 个答案:

答案 0 :(得分:2)

如果您的所有B个对象仅与一个A对象相关联,则可以在迁移中执行以下操作:

migration.deleteData("B")
migration.enumerate("A") { oldObject, newObject in
    let b = migration.create("B", value: oldObject!["b"]!)
    (newObject!["bs"] as! List<MigrationObject>).append(b)
}

这解决了以下事实:您无法通过删除所有现有newObject来保留属性b,而无法获取与B兼容的链接对象的引用对象,而是链接到它们的新副本。