【问题标题】:Core Data Primary Key核心数据主键
【发布时间】:2010-10-28 10:46:12
【问题描述】:

这可能看起来很愚蠢,但我仍然不知道如何在 xcdatamodel 文件中将属性标记为主键。 我的持久存储是 sqlite 文件。 谁能帮帮我?

在这种情况下,我如何“验证”一个 ID 是唯一的? 我应该写一个验证方法还是什么?

【问题讨论】:

    标签: iphone cocoa-touch core-data


    【解决方案1】:

    您的选择是:

    • 使用-[NSManagedObject objectID]。请注意,此 ID 是临时的,直到第一次保存对象或您调用 -[NSManagedObjectContext obtainPermanentIDsForObjects:error:]
    • 使用CFUUID 系列函数为-awakeFromInsert 方法中的每个对象生成一个UUID
    • 创建您自己的类似主键的系统,在模型中存储一个整数并随着每个对象的创建而递增

    没有很好的方法来验证属性是否唯一。您将得到的最接近的方法是确保它在创建时是唯一的,然后实现一个自定义的 setter 方法来阻止任何人更改 ID。

    【讨论】:

    • 一个更有建设性的答案 - 你应该被标记为解决方案!
    • 生成 UUID 是最好的方法。我们在我们的应用程序中使用它,它的服务非常好。
    【解决方案2】:

    请记住,Core Data 是一个对象图持久性框架,而不是数据库。像主键这样的东西被抽象出来了,因为它们依赖于持久存储的实现。

    【讨论】:

    • 这应该是@Mugunth 应该选择的答案!感谢您的洞察力。
    • 那么Core Data会自己生成主键吗?
    【解决方案3】:

    Core Data 有自己的主键——您不必添加主键。您可以使用检索它

    NSManagedObjectID *moID = [managedObject objectID];
    

    【讨论】:

      【解决方案4】:

      有时当黑客需要主键的实际 int 时。以下是如何抓住它:

      NSManagedObjectID *yourManagedObjectID = [yourManagedObject objectID];
      int yourManagedObject_PK = [[[[[yourManagedObjectID URIRepresentation] absoluteString] lastPathComponent] substringFromIndex:1] intValue];
      

      尽管 CoreData 是一个对象图,但如果查看 CoreData 生成的 SQLite 数据库数据,这种获取 NSManagedObject 主键的方式应该没有问题。 ii 在同一代码中一起使用了 CoreData 和低级 sqlite3 C 库,并将主键从 CoreData 传递到 sqlite3 以获取记录工作得很好。

      !如果您打算在生产中使用此代码,请注意 db 主键转换为 URIRepresentation 的方式可能发生的内部更改,它可能会破坏您的代码。

      享受

      【讨论】:

      • 对象 ID 和 SQLite RID 之间没有定义任何关系。只能用于特定版本的临时密钥,但对于持久 主密钥 的方法是错误的,因为它可以在其他版本中被静默破坏。
      • 您所说的“在其他版本中损坏”到底是什么意思?为什么要改变主键?
      • PK 值不会改变,但是使 URL 表示的算法可能会改变,因为官方没有定义算法。在这种情况下,您的代码不能保证提取有效的 PK 值。 (如果您有任何来源定义了算法,请告诉我,然后我会推荐您发布)
      • 好的。 有时当黑客攻击部分是令人信服的。我的反对票目前已锁定,因此您进行一些编辑,我将删除反对票。
      • 为了速度和效率,有时会选择 sql。我的例子是一个包含计数(*)、总和、平均值和组的查询。它在 OO 中做起来很痛苦,对于 sql 来说是单行!那个'hack'完美地工作,如果Apple改变它,那么他们仍然必须以某种方式使sql join工作,所以我想我们暂时还可以;)。投票赞成,即使理论上我们不应该这样做。在我看来,完全隐藏数据库是一个错误,更多的是由原则驱动,而不是真正的技术原因。我们这样做,通过 SQL 获取批次。即使有可用的框架,也一直在许多其他系统中。
      【解决方案5】:

      无需破解 NSManagedObjectID,您就可以在管理远程数据收集之前快速检查您的属性。

      我做了一个实用方法,check it here

      【讨论】:

        【解决方案6】:

        用于检索主键的 Swift 扩展

        extension NSManagedObject {
            var primaryKey : String {
                guard objectID.uriRepresentation().lastPathComponent.count > 1 else { return "" }
                return objectID.uriRepresentation().lastPathComponent.substring(from: 1)
            }
        }
        

        对于字符串

        extension String
        {
            func substring(from : Int) -> String {
                guard self.count > from else { return "" }
                return String(self[self.index(self.startIndex, offsetBy: from)...])
             }
        }
        

        【讨论】:

          【解决方案7】:

          我宁愿使用时间 + 类名作为唯一标识符。

          【讨论】:

          • 不太推荐,什么时候能保证同时创建的对象不超过一个?
          • 也不推荐。此方法不能保证密钥是唯一的。
          • @Fynh 我发布了代码,不过我的帖子可能不完整,我总是在同步时间获取方法。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-01-04
          • 2023-03-19
          • 2011-09-17
          • 1970-01-01
          • 1970-01-01
          • 2010-11-12
          • 2012-10-24
          相关资源
          最近更新 更多