领域 - 无法使用现有主键值创建对象

时间:2016-11-14 15:32:37

标签: ios swift realm realm-mobile-platform

我有一个对象有许多狗的人。应用程序有单独的页面,它只显示狗和其他显示人的狗

的页面

我的模型如下

class Person: Object {
    dynamic var id = 0
    let dogs= List<Dog>()

    override static func primaryKey() -> String? {
        return "id"
    }
}

class Dog: Object {
    dynamic var id = 0
    dynamic var name = ""

    override static func primaryKey() -> String? {
        return "id"
    }
}

我有人存储在Realm中。人有详细页面,我们取,并显示他的狗。如果狗已经存在,我会更新该狗的最新信息并将其添加到人的狗列表中,否则创建新狗,保存并将其添加到人员列表中。这适用于coredata。

// Fetch and parse dogs
if let person = realm.objects(Person.self).filter("id =\(personID)").first {
    for (_, dict): (String, JSON) in response {
        // Create dog using the dict info,my custom init method
        if let dog = Dog(dict: dict) {
            try! realm.write {
                // save it to realm
                realm.create(Dog, value:dog, update: true)
                // append dog to person
                person.dogs.append(dog)
            }
        }
    }
    try! realm.write {
        // save person
        realm.create(Person.self, value: person, update: true)
    }
}

在尝试用他的狗更新人时,领域会抛出异常 无法使用现有主键值

创建对象

2 个答案:

答案 0 :(得分:29)

这里的问题是,即使你正在创建一个全新的Realm Dog对象,你实际上并没有将它保存到数据库中,因此当你调用append时,你就是'重新尝试添加第二个副本。

当您调用realm.create(Dog, value:dog, update: true)时,如果数据库中已存在具有该ID的对象,您只需使用您创建的dog实例中的值更新该现有对象,但{ {1}}实例仍然是一个独立的副本;它不是数据库中的dog对象。您可以通过检查Dog是否等于dog.realm来确认。

因此,当您调用nil时,由于person.dogs.append(dog)尚未在数据库中,因此Realm会尝试创建一个全新的数据库条目,但由于已经有一只带有该ID的狗而失败。

如果要将dog对象附加到dog,则需要查询Realm以检索引用数据库中条目的正确person对象。值得庆幸的是,使用主键支持的Realm对象非常简单,因为您可以使用dog方法:

Realm.object(ofType:forPrimaryKey:)

答案 1 :(得分:0)

我们不再需要TiM的方法。

使用add(_:update:)

try realm.write {
    realm.add(objects, update: Realm.UpdatePolicy.modified)
    // OR
    realm.add(object, update: .modified)
}

Realm.UpdatePolicy枚举:

error (default)
modified //Overwrite only properties in the existing object which are different from the new values.
all //Overwrite all properties in the existing object with the new values, even if they have not changed
  

NB:可在Realm Swift 3.16.1上运行