【问题标题】:how to add primary key to realm objects如何将主键添加到领域对象
【发布时间】:2021-07-22 14:34:41
【问题描述】:

我正在尝试使我的领域对象能够从应用程序中进行编辑。这是我的课:

import Foundation
import RealmSwift

class Category: Object {
    @objc dynamic var name: String = ""
    let items = List<Item>()
}

 

这就是我创建该类的实例的方式:

        let action = UIAlertAction(title: "Add", style: .default) { action in
            
            let newCategory = Category()
            newCategory.name = textField.text!
            
            self.save(category: newCategory)
        }
    
       

这是我的编辑方法:


func edit(category: Category) {
        do {
            try realm.write {
                realm.add(category, update: .all)
            }
        }catch {
            print("error editing category \(error)")
        }
    }

这就是我在按下编辑按钮时在 IBAction 中调用我的编辑方法的方式

let saveAction = UIAlertAction(title: "Save Changes", style: .default) { action in
            
            let editedCategory = Category()
            editedCategory.name = textField.text!
            
            self.edit(category: editedCategory)

        }

我得到的错误是:“由于未捕获的异常'RLMException'而终止应用程序,原因:''Category'没有主键并且无法更新'”

我尝试在我的类别类中添加主键,但仍然没有用。有什么帮助吗?

【问题讨论】:

  • 你重写了primaryKey函数吗?关注文档:academy.realm.io/posts/realm-primary-keys-tutorial
  • 您能否详细说明一下您是如何在类别类中添加主键的,但它仍然不起作用?请更新您的代码示例并添加主键
  • 您不需要主键。在本地领域情况下,它完全是可选的。但是,使用一个是个好主意,如果您编辑对象,那么它允许您 upsert 它们这是您的代码在此处尝试执行的操作 add(category, update: .all) 需要一个主键。请查看Read and Write 指南,因为它会解决很多问题。

标签: ios swift xcode realm primary-key


【解决方案1】:

Realm 指南Read and Write Data 中涵盖了很多内容,但让我也提供一些细节。请注意,此答案反映了 Swift 10.10.0 之前的版本,并且在更高版本中有所更改。

您尝试使用的方法

realm.add(category, update: .all)

被称为“upsert”并且需要对象中的主键。

一个 upsert 插入或更新一个对象取决于 对象已经存在。 Upsert 要求数据模型具有 主键。

所以让我们重新工具 Category 对象以包含一个主键 _id

class Category: Object {
    @objc dynamic var _id: ObjectId = ObjectId.generate()
    @objc dynamic var name: String = ""
    let items = List<Item>()

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

然后,当一个对象被创建时

let newCategory = Category()
newCategory.name = textField.text!
let realm = try! Realm()
try! realm.write {
   realm.add(newCategory)
}

它会有一个主键

从那时起,您可以在 write 中修改对象,也可以通过其主键对其进行 upsert。

let someId = //the id of the newCategory created above
try! realm.write {
   let anotherCat = Category(value: ["_id": someId, "name": "Frank"])
   realm.add(anotherCat, update: .modified)
}

上面的代码会用新名字更新原来的newCategory对象,因为_id是一样的

【讨论】:

  • 感谢您的回答,但是当我尝试这样做时,出现以下错误:尝试使用现有主键值“60fb33c9c687b78540419c61”创建“类别”类型的对象。
  • @LukaVujnovac 哎呀。对象初始化在错误的位置。它应该在里面写。我已经更正了代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多