领域迁移引入主键

Realm migration introducing primary key

目前,我的 Realm 数据库包含 MyData 个对象的普通数组:

class MyData: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
}

例如,它可能包含

[
    ["Alice", 12],
    ["Bob", 13],
    ["Alice", 22],
    ["Carolina", 13],
    ["Bob", 20]
]

我将对其进行返工,使 name 保持最大的独特性 age:

[
    ["Alice", 22],
    ["Bob", 20],
    ["Carolina", 13]
]

另外,我想将 name 设为主键以避免将来重复。

所以我将 class 描述更改为

class MyData: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    override static func primaryKey() -> String? {
        return "name"
    }
}

现在我需要提供一个迁移块:

let config = Realm.Configuration(
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        switch oldSchemaVersion {
        case 0:
           migration.enumerateObjects(ofType: MyData.className()) { (oldObject, newObject) in
            // how to do it?
        }
        default:
            break
    }
})

我不明白在枚举块中要做什么。在我的示例中,我有五个 "old" 对象(没有主键),我将有三个 "new" 对象(有主键),那么我该如何进行转换?

func realmConfiguration(schemaVersion: UInt64) {
       let config = Realm.Configuration(schemaVersion: schemaVersion,
                                        migrationBlock: { _, oldSchemaVersion in
                                            if oldSchemaVersion < schemaVersion {}
       })
       Realm.Configuration.defaultConfiguration = config
   }

在 appDelegate 中调用此函数

//Bump the schemaVersion when ever you need migration
realmConfiguration(schemaVersion: 2)

您是否只是尝试增加架构版本并将 属性 deleteRealmIfMigrationNeeded 添加到 true ?

Realm.Configuration.defaultConfiguration = Realm.Configuration(
    schemaVersion: 2,
    migrationBlock: { migration, oldSchemaVersion in },
    deleteRealmIfMigrationNeeded: true
)

编辑:

抱歉,这不是真的,因为您只需要保留最老的人,所以请尝试使用领域迁移对象的 delete 方法:

let config = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
    switch oldSchemaVersion {
    case 0:
       var objects: [String: Any] = []
       migration.enumerateObjects(ofType: MyData.className()) { 
       (oldObject, newObject) in
           if let age = oldObject["age"] as? Int, age > objects[oldObject["name"]] {
               migration.delete(oldObject["name"])
               objects[oldObject["name"]] = oldObject
           } else {
               migration.delete(oldObject)
           }

       }
    default:
        break
    }
})

https://realm.io/docs/swift/latest/api/Classes/Migration.html#/s:FC10RealmSwift9Migration6deleteFCS_13DynamicObjectT_