• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 从核心数据中的关系中删除对象的正确方法

[复制链接]
菜鸟教程小白 发表于 2022-12-12 10:24:47 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我有一个包含两个实体的简单数据模型:个人和公司。一个人可以分配给很多公司,一个公司可以分配给很多人。我已经用 1 家公司和 2 个人填充了数据库,并将所有人分配给公司。在填充数据库的过程中,Core Data 会生成如下所示的日志:

CoreData: sql: INSERT INTO ZCOMPANY(Z_PK, Z_ENT, Z_OPT, ZNAME) VALUES(?, ?, ?, ?)
CoreData: sql: INSERT OR REPLACE INTO Z_1PERSONS(Z_1COMPANIES, Z_2PERSONS) VALUES (1, 2)
CoreData: sql: INSERT OR REPLACE INTO Z_1PERSONS(Z_1COMPANIES, Z_2PERSONS) VALUES (1, 1)
CoreData: sql: INSERT INTO ZPERSON(Z_PK, Z_ENT, Z_OPT, ZNAME) VALUES(?, ?, ?, ?)
CoreData: sql: INSERT INTO ZPERSON(Z_PK, Z_ENT, Z_OPT, ZNAME) VALUES(?, ?, ?, ?)

接下来我关闭应用程序,再次启动它并删除公司。然后Core Data执行以下操作:

CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1PERSONS t1 JOIN ZPERSON t0 ON t0.Z_PK = t1.Z_2PERSONS WHERE t1.Z_1COMPANIES = ? 
CoreData: annotation: sql connection fetch time: 0.0009s
CoreData: annotation: total fetch execution time: 0.0018s for 2 rows.
CoreData: annotation: to-many relationship fault "persons" for objectID 0x8d281e0 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Company/p1> fulfilled from database.
Got 2 rows
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME FROM ZPERSON t0 WHERE  t0.Z_PK = ? 
CoreData: annotation: sql connection fetch time: 0.0008s
CoreData: annotation: total fetch execution time: 0.0016s for 1 rows.
CoreData: annotation: fault fulfilled from database for : 0x8e19940 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p1>
CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1PERSONS t1 JOIN ZCOMPANY t0 ON t0.Z_PK = t1.Z_1COMPANIES WHERE t1.Z_2PERSONS = ? 
CoreData: annotation: sql connection fetch time: 0.0009s
CoreData: annotation: total fetch execution time: 0.0022s for 1 rows.
CoreData: annotation: to-many relationship fault "companies" for objectID 0x8e19940 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p1> fulfilled from database.
Got 1 rows
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME FROM ZPERSON t0 WHERE  t0.Z_PK = ? 
CoreData: annotation: sql connection fetch time: 0.0006s
CoreData: annotation: total fetch execution time: 0.0014s for 1 rows.
CoreData: annotation: fault fulfilled from database for : 0x8e18f90 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p2>
CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1PERSONS t1 JOIN ZCOMPANY t0 ON t0.Z_PK = t1.Z_1COMPANIES WHERE t1.Z_2PERSONS = ? 
CoreData: annotation: sql connection fetch time: 0.0006s
CoreData: annotation: total fetch execution time: 0.0015s for 1 rows.
CoreData: annotation: to-many relationship fault "companies" for objectID 0x8e18f90 <x-coredata://0AFFC353-8C34-43AD-8D30-4483FB44BEA4/Person/p2> fulfilled from database.
Got 1 rows
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: DELETE FROM ZCOMPANY WHERE Z_PK = ? AND Z_OPT = ?
CoreData: sql: DELETE FROM Z_1PERSONS WHERE Z_1COMPANIES = 1
CoreData: sql: UPDATE ZPERSON SET Z_OPT = ?  WHERE Z_PK = ? AND Z_OPT = ?
CoreData: sql: UPDATE ZPERSON SET Z_OPT = ?  WHERE Z_PK = ? AND Z_OPT = ?
CoreData: sql: COMMIT

正如我们所见,Core Data 从数据库中获取分配给已删除公司的所有人员。接下来,它为每个人获取公司集合。最终预期的删除操作在数据库上执行:

DELETE FROM ZCOMPANY WHERE Z_PK = ? AND Z_OPT = ?
DELETE FROM Z_1PERSONS WHERE Z_1COMPANIES = 1

当我删除公司时,一个 managedObjectContext 是清除的(其中没有注册对象),因此没有理由清除内存中的无效关系,因为内存中没有对象。唯一应该做的是上面列出的数据库级删除操作。

情况有问题,因为当我有1000人分配到公司时,删除公司的操作需要太多时间(以秒计)。

删除只执行必要操作并确保数据一致性的公司的正确方法是什么?

您可以在这里下载为解决问题而准备的 Xcode 项目: Xcode project



Best Answer-推荐答案


Core Data 不是数据库。 Core Data 是一个可以保存到数据库的对象层次结构。

在这种情况下,这是一个重要的区别。当您删除某些内容时,Core Data 将检索关系两侧的对象,以确保保留引用完整性。使用 SQLite,这似乎效率低下(确实如此)。当商店是其他东西时,需要仔细检查。

那么,如何解决这个问题?一是承认删除需要一些时间并启动一个后台私有(private)队列来处理删除。不是最优的。

另一种选择是在这两个表之间使用软引用。同样不理想。

如果您可以等到 iOS 8,您可以进行批量更新以消除关系。

关于ios - 从核心数据中的关系中删除对象的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24265742/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap