Swift 核心数据 NSPredicate

Posted

技术标签:

【中文标题】Swift 核心数据 NSPredicate【英文标题】:Swift Core Data NSPredicate 【发布时间】:2017-12-11 05:55:17 【问题描述】:

我想要完成什么?

我有一个包含三个核心数据实体的应用:成分、Cookie 和 CookieIngredients。

成分是鸡蛋、牛奶、黄油等,还有一个布尔值表示我的厨房里是否有这种成分。 饼干有巧克力片、燕麦葡萄干等。 CookieIngredients 是每个 cookie 所需的每种成分的单位。

我希望能够根据我指示的厨房中的哪些成分显示我可以制作哪些饼干。

我做了什么?

我已成功将我的应用程序置于所有这些实体都在 Core Data 中进行管理的状态,并且我能够毫无问题地将配料标记为“在我的厨房中”。我可以根据成分和标题搜索 Cookie。

我卡在哪里了?

我一直找不到任何示例来帮助理解如何创建一个 NSPredicate 以将我的 FetchedResultsController 限制为仅 Cookie 的所有 CookieIngredient 的成分都在“我的厨房”。如果这是一个使用 mysql 数据库的 Web 应用程序,我可以通过一些内部连接来做到这一点,但我不知道如何使用 Core 实现类似的东西——或者即使有可能做这样的事情数据。

【问题讨论】:

【参考方案1】:

类似下面的谓词应该可以工作:

let predicate = NSPredicate(format: "ALL ingredients.inKitchen = YES")

这假设您的 Cookie 实体具有 ingredients 关系,并带有一个名为 inKitchenboolean 标志。

【讨论】:

我觉得你是对的,这应该可行。我确实Cookie 上有一个ingredients 关系,在Ingredients 实体上有一个Boolean 标志。但它不起作用。我得到Unsupported predicate ALL items.in_kitchen == 1。谓词如下所示:NSPredicate(format: "ALL items.in_kitchen = true") 任何想法我可能做错了什么? 仅供参考:我尝试将其更改为 == 而不是 = 但仍然没有骰子。【参考方案2】:

如果您要获取Cookie 对象,则谓词需要遍历与CookieIngredient 的(对多)关系以及与Ingredient 的(一对一)关系。所以谓词应该是这样的:

let predicate = NSPredicate(format: "ALL cookieIngredients.ingredient.inKitchen = YES")

这假定从CookieCookieIngredient 的关系称为“cookieIngredients”,而从CookieIngredientIngredient 的关系称为“成分”。

我发现 CoreData 对多对关系(即 ANY、ALL、NONE、SOME)的解析有点不可预测,所以我倾向于使用 SUBQUERY 来获得我想要的结果。在上述情况下,(注意 ALL inKitchen = YES 相当于说 none has inKitchen = NO)我会使用:

let predicate = NSPredicate(format: "SUBQUERY(cookieIngredients, $X, $X.ingredient.inKitchen == NO).@count == 0")

【讨论】:

我用NSPredicate(format: "ALL cookieIngredients.in_kitchen == true") 尝试了第一个版本,它只是抛出了Unsupported predicate ALL 错误。在这种情况下,cookieIngredients 是 Cookie 实体与成分实体的关系。 \n 我还尝试了NSPredicate(format: "SUBQUERY(cookieIngredients, $X, $X.in_kitchen == false).@count == 0") 的第二个版本,它不会崩溃,但它也不会返回正确的 Cookie。它不会返回系统中的所有 cookie,但它确实返回了一堆我没有所有成分的cookie。 这里有一个想法:目前Cookie实体到成分实体的关系在两端配置为“对多”,因为一个cookie可以有多种成分,一种成分可以用于多种饼干。我有错吗?应该只在一个方向上设置为“对多”吗? 我对您的模型感到困惑 - 您可以编辑您的问题以包含图片吗? dropbox.com/s/b21s23kcx18l2xj/… 谢谢 - 我将直接多对多关系与通过中间配方实体的关系混为一谈。但我看到你找到了正确的组合!【参考方案3】:

解决方案!

这是对我有用的谓词:

NSPredicate(format: "SUBQUERY(cookieIngredients, $X, $X.in_kitchen == true).@count == cookieIngredients.@count")

【讨论】:

以上是关于Swift 核心数据 NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章

swift 3 - 核心数据关系 - 获取数据

swift中的核心数据

Swift 3 核心数据问题 - 所有数据丢失

Swift 3 核心数据

Swift - 如何将输入数据保存到核心数据中?

排序核心数据获取(swift 4)