【问题标题】:iOS Core Data - Saving the similar object is not overriding the old objectiOS Core Data - 保存相似对象不会覆盖旧对象
【发布时间】:2022-08-19 04:02:13
【问题描述】:

我是 Core Data 的新手,我在保存对象时遇到了问题。 我想要一种可以保存相同对象的行为(对我而言,这意味着它具有相同的 id - 主键)并且它不会为相同的 id 创建新条目。

我相信它类似于使用 sqlite 的 Android ROOM 中的 OnConflictStrategy.REPLACE。

这是我添加到 Core Data 的 post 方法。我正在使用合并策略,但它仍然无法正常工作。

    static func addPost(post:Post){
        guard let context = context else {
            print(\"post add error with context core data\")
            return
        }
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        let p = PostDao(context: context)
        p.id = post.id
        p.username = post.username
        p.title = post.title
        p.photo = post.photo
        p.location = post.location
        p.contactPhone = post.contactPhone
        p.isPostDeleted = post.isPostDeleted!
        p.postDescription = post.postDescription
        p.lastUpdated = post.lastUpdated
        p.contactEmail = post.contactEmail
        
        do{
            try context.save()
        }catch let error as NSError{
            print(\"post add error core data\\(error) \\(error.userInfo)\")
        }
    }
class Post{
    
    public var id: String? = \"\"
    public var title: String? = \"\"
    public var username: String? = \"\"
    public var postDescription: String? = \"\"
    public var photo: String? = \"\"
    public var location: String? = \"\"
    public var contactPhone: String? = \"\"
    public var contactEmail: String? = \"\"
    public var isPostDeleted: Bool? = false
    public var lastUpdated:Int64 = 0
    
    init(){}
    
    init(post:PostDao){
        id = post.id
        title = post.title
        postDescription = post.postDescription
        username = post.username
        photo = post.photo
        isPostDeleted = post.isPostDeleted
        lastUpdated = post.lastUpdated
        location = post.location
        contactPhone = post.contactPhone
        contactEmail = post.contactEmail
    }
    
}

extension PostDao {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<PostDao> {
        return NSFetchRequest<PostDao>(entityName: \"PostDao\")
    }

    @NSManaged public var id: String?
    @NSManaged public var title: String?
    @NSManaged public var username: String?
    @NSManaged public var photo: String?
    @NSManaged public var postDescription: String?
    @NSManaged public var location: String?
    @NSManaged public var contactPhone: String?
    @NSManaged public var contactEmail: String?
    @NSManaged public var isPostDeleted: Bool
    @NSManaged public var lastUpdated: Int64

}

extension PostDao : Identifiable {

}

我的数据模型:

  • 如果要更新现有对象,您需要首先从上下文中获取它(使用 id)并更新该对象。你不能创建一个新的并期望 Core Data 理解它应该替换现有的。
  • 只是创建一个新对象?它不难的核心数据不知道 id 是主键,直到你给出指令才用新的上下文再次保存帖子?
  • 但你为什么要在这里重复?它在逻辑上不正确尝试开箱即用

标签: ios swift core-data nsmergepolicy


【解决方案1】:

Core Data 不知道主键是什么,所以它不关心id 是否有重复值。这不是 SQL,用 SQL 术语思考是错误的。

如果要防止重复 ID,则需要在模型编辑器中添加唯一性约束。在您的屏幕截图中,在右侧显示“约束”的位置,单击“+”按钮。这将在表格中添加一行。编辑该行以添加您想要唯一的属性 - 只需 id,仅此而已。然后,Core Data 会将其用作唯一属性。如果您使用相同的id 创建一个新对象,Core Data 将使用合并策略来确保您不会得到重复的id

请记住,唯一性约束不仅仅是“主键”的另一个名称。由于不同的原因,它的工作方式不同,但在这种情况下恰好会产生类似的结果。

【讨论】:

    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多