如何为给定的 Core Data 实体创建和保存一组对象/数组?

Posted

技术标签:

【中文标题】如何为给定的 Core Data 实体创建和保存一组对象/数组?【英文标题】:How do I create and save a set/array of objects for a given Core Data entity? 【发布时间】:2016-12-13 21:53:18 【问题描述】:

我有一个应用程序,可以理想地比较豪华餐厅及其各自的菜肴。这意味着我有一个名为Restaurant 的核心数据实体,其属性包括restaurantNamelocationaveragePricefoodType。我还有一个名为 MenuItem 的第二个核心数据实体,具有 foodNamecaloryCountpricerating 等属性。

由于目标是比较,例如,两个牛排馆及其菲力牛排的卡路里/价格/评级,我真的很想获取我拥有的 MenuItem 对象的预加载列表(一个名为 selectedMenuItems 的数组)并以某种方式将其保存为 Restaurant 实体的属性,以便每个单独的餐厅都将附加这些菜单项对象的实例(之后用户可以编辑餐厅每个菜单项的卡路里/价格/评级按餐厅计算)。在最理想的情况下,如果从 selectedMenuItems 对象数组中添加或减去任何内容,它将反映在所有单独的餐厅中。

到目前为止我已经尝试过:

1.) RestaurantMenuItem 之间的多对多关系

正如您可能从我上面的描述中猜到的那样,这并没有达到我想要的效果,因为它只将每个餐厅连接到 selectedMenuItems 数组,并且在餐厅中所做的任何更改都通过与数组(就我而言,这是对关系的根本误解)。

2.) 在Restaurant 中创建一个Transformable 类型的属性来保存selectedMenuItems 数组

这看起来似乎可以工作一会儿。正如我所说,我在我的 Restaurant 类型的 Transformable 实体中创建了一个名为 menuItems 的属性,然后在每个餐厅的详细视图的视图控制器中(显示 menuItems 的视图控制器是一个额外的导航步骤)我在viewDidLoad() 中添加以下内容:

// The selected Restaurant is passed from the prior screen to restaurant
restaurant.menuItems = selectedMenuItems as NSObject?

这似乎是我所需要的,除了如果我对 selectedMenuItems 数组进行任何更改,它会导致应用程序崩溃并显示控制台读数 'NSInvalidArgumentException', reason: '-[Restaurant encodeWithCoder:]: unrecognized selector sent to instance

3.) 将 objectsselectedMenuItems 数组拆分为 properties

的匹配数组

在对 2.) 做了一些实验之后,似乎有一个对象数组是问题所在。正因为如此,我遍历了selectedMenuItems 并将属性剥离到它们自己的数组中(foodNameArraycaloryCountArraypriceArray 等)。之后,我将它们中的每一个分配给我的Restaurant 实体的新创建属性:

    restaurant.foodNames = foodNameArray as NSObject?
    restaurant.caloryCounts = caloryCountArray as NSObject?
    restaurant.prices = priceArray as NSObject?

现在,这已经看起来非常狡猾并且容易发生灾难性的失败。然而,它确实按照我想要的方式工作。这里的问题是,对selectedMenuItems 的任何更改(例如添加/删除新对象)在第一次加载后都没有传递到我的餐厅。这与 1.) 相比,其中更改从餐厅传播到 selectedMenuItems(从下到上)与 3.) 相比,我希望更改从上到下流动。

鉴于上述描述,是否有人对我如何获得我正在寻找的功能提出建议?

【问题讨论】:

【参考方案1】:

我会使用三个实体,而不是多对多关系:

Restaurant,就像你现在拥有的一样; Dish,代表通用菜单项,例如“菲力牛排”或“肋眼”;和 MenuItem,这是由特定 Restaurant 服务的特定 Dish

因为Dish 是通用的,所以它只有一个属性foodName(尽管您可能需要其他属性)。 MenuItem 将具有属性 caloryCountpricerating

由于每个MenuItem 代表特定餐厅供应的特定菜肴,因此它与RestaurantDish 具有“一对一”关系。对于每一种关系,逆向将是“对多”:一家餐厅将提供许多 MenuItems,而 Dish 可以在许多 MenuItems 中提供服务。

然后,您可以预加载菜肴列表,用户可以从中选择特定餐厅提供的菜肴。然后您可以创建相应的MenuItems,并且大概可以让用户记录卡路里/价格/等级。如果用户删除了 MenuItem,则相应的 Dish 不受影响,因此可用于其他现有和/或新餐厅。如果用户想要添加一个没有现有 Dish 的 MenuItem,您可以添加一个新 Dish,该 Dish 将可用于任何后续的 MenuItem。

【讨论】:

这听起来令人难以置信,非常感谢您的彻底回答!今晚晚些时候我会在下班后尝试一下,如果它运行正常,我会将您的回答标记为解决了我的问题。 我没有时间完全设置和测试,但我认为这正是我想要的。你是救生员,非常感谢!

以上是关于如何为给定的 Core Data 实体创建和保存一组对象/数组?的主要内容,如果未能解决你的问题,请参考以下文章

Core Data 中关系的默认值

Core Data 如何为关系设置值?

在 Swift Core Data 中保存没有关系的实体

如何为一对多关系正确配置 Core Data 数据模型和 NSManagedObject?

如何为依赖于关系的自定义 Core Data 属性发布通知?

Entity Framework Core - 如何处理相关实体映射和保存