如何组织具有循环依赖的 Core Data 实体?

Posted

技术标签:

【中文标题】如何组织具有循环依赖的 Core Data 实体?【英文标题】:How to organize Core Data entities that have circular dependencies? 【发布时间】:2012-11-09 07:01:19 【问题描述】:

这是一个关于如何最好地组织 Core Data 中 NSManagedObjects 之间关系的概念性问题。

当出现循环依赖时,如何在 Core Data 中组织实体?

例如,假设我正在开发一个社交食谱应用。这个应用程序允许您根据谁在制作每个食谱以及谁在购买每种食材来组织膳食。此外,每个食谱都是由不同的人创建的。因此,我提出以下 NSManagedObjects 及其各自的属性和关系:

Chef = uniqueID(字符串),用户名(字符串),技能(字符串)>>recipesToMake =(对多)Recipe>> IngredientsToBuy =(对多) Ingredient

Recipe = uniqueTitle(字符串),作者ID(字符串)>>成分=(对多)Ingredient

Ingredient = 姓名(字符串)、卡路里(整数 64)

问题

[_] 如果我有多个 Chef 处理同一个配方,这是否意味着同一 Recipe 对象的多个副本存储在 Core Data 中,每个副本属于一个单独的 Chef?如果是这样,可以吗?如果没有,我如何在 Core Data 中创建一个 Recipe 对象并让多个 Chef 指向它,而 Chef 本身可以通过 recipesToMake 指向许多 Recipe 对象?

[_] 如果给定一个配方,我将如何检查分配给它的 Chef ?我会在 Core Data 中获取那些指向具有给定uniqueTitle 属性的Recipe 对象的Chef 对象吗?

[_] 由于Chef 对象可以指向许多Recipe 对象,因此将每个Recipe 的作者作为包含作者唯一ID 的Recipe 的属性存储是否正确?我最初会考虑创建一个从Recipe 到一个Chef 的关系,但这会在ChefRecipe 对象之间创建另一个循环依赖关系。

[_] 再一次,如果Chef 可以通过ingredientsToBuy 指向许多Ingredient 对象,并且Recipe 可以通过ingredients 指向许多Ingredient 对象,那么会有很多吗? CoreData 中同一 Ingredient 对象的多个副本?

[_] 如果我允许Recipe 对象拥有任意数量的作者,我将如何实现它?使用与 Chef 对象的关系似乎会创建循环依赖关系,而使用连接到 Chef uniqueID 的属性似乎需要预先指定每个 Recipe 对象的最大作者数。

【问题讨论】:

好问题!!! 1 年前,我尝试做与 Resource Project 相同的事情。并没有做,然后我在没有使用核心数据的情况下解决了这个项目。后来我用 Project 的副本重新解决了这个项目。而且我知道这不是一个好方法。即使我在等待答案....感谢发布这个问题:) 【参考方案1】:

“循环依赖”一词在这里被否定使用,但您在 Core Data 中真正指的是关系和逆关系,实际上是推荐的。

当您构建一个类系统时,循环依赖是不需要的,这些类在两个方向上相互依赖过多,也称为耦合。它们确实是不可取的,但它更多地与代码流和逻辑有关,而不是在处理数据关系时。

以下是您问题的答案:

    您有责任在代码中强制执行食谱的唯一性,这意味着您必须定义使两个食谱成为“相同”食谱的品质。您甚至可以比较配方的每种成分,或者只需使用 uniqueTitle 即可比较配方的独特性。有了它,您可以实现“更新或创建”设计模式,您首先通过其主键查找配方,在更简单的场景中是唯一标题。如果它已经存在,那么您可以简单地读取和/或更新该对象。否则将其创建为新的托管对象。对它的后续查询将获取刚刚创建的对象。然后,每个厨师都可以与该单个食谱对象建立关系。

    对于每个关系,最好也定义反向关系。在 Recipe 对象中,将其称为“ChefsMaking”,这可能是指向 Chef 对象的一对多关系。 (它们结合起来形成“多对多”的关系)。在 Xcode 中,每个关系都有一个下拉框,您可以在其中设置其逆向关系。

    我确实相信它可以创建多个引用相同类型对象的关系。这里有两种从食谱指向厨师的关系。一个是“ChefsMaking”,一种对多的关系。另一个是“Author”,一种一对一的关系,与之相反的是 Chef 对象中的一对多“RecipesAuthored”关系。

    答案 1 中的相同原则适用于此。定义成分的唯一性,并让您的 Chefs 和 Recipes 通过获取已存在的成分(通过其主键)或创建新的成分来指向成分。

    只需重命名您的关系作者,并使其成为一对多关系。

希望这会有所帮助!

【讨论】:

谢谢!我误解了多对多关系的概念。 就标题而言,如果我有一个反向关系,那么这不会创建一个循环包含依赖项吗?每个标题都必须包含另一个才能知道关系的类?

以上是关于如何组织具有循环依赖的 Core Data 实体?的主要内容,如果未能解决你的问题,请参考以下文章

IOS/objective-c/core-data:如何从相关实体获取属性

iPhone Core Data - 访问具有多种关系的深层属性

Core Data 中线程安全的唯一实体实例

SwiftUI 将 Core Data 实体读入 []

iPhone如何使用NSPredicate按父实体过滤Core Data?

如何将实体上的属性迁移到 Core Data 中的实体