首页 文章

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

提问于
浏览
6

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

我的模型如下

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)
    }
}

试图用他的狗更新人,领域抛出异常 Can't create object with existing primary key value

1 回答

  • 26

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

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

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

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

    if let person = realm.object(ofType: Person.self, forPrimaryKey: "id") {
        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)
                    //get the dog reference from the database
                    let realmDog = realm.object(ofType: Dog.self, forPrimaryKey: "id")
                    //append dog to person
                    person.dogs.append(realmDog)
                }
            }
        }
        try! realm.write {
            //save person
            realm.create(person .self, value: collection, update: true)
        }
    }
    

相关问题