对多关系的简单核心数据获取

Posted

技术标签:

【中文标题】对多关系的简单核心数据获取【英文标题】:Simple Core Data fetch for to-many relationship 【发布时间】:2020-01-03 21:34:20 【问题描述】:

鉴于 Dogs 和 Owners 之间是一对多的关系,即

(Owner)
@NSManaged public var dogs: NSSet?

(Dog)
@NSManaged public var owners: NSSet?

我有一个返回 Dogs 的 DogProvider 类。它默认返回所有 Dogs。但是在我给 DogProvider 一个所有者的情况下,我如何在 NSFetchedResultsController 中只返回该所有者的狗?我知道以下方法不起作用 (Cannot convert value of type 'Owner?' to expected argument type '[Any]?') 但这是我的最新尝试。

let fetchRequest: NSFetchRequest<Dog> = Dog.fetchRequest() //return all dogs by default
if let owner = self.owner 
    fetchRequest.predicate = NSPredicate(format: "owner = %@", argumentArray: self.owner)

【问题讨论】:

您可以像访问任何其他属性一样访问关系,例如 owner.dogsdog.owner 我明白,但视图控制器期待dogProvider.fetchedResultsController.fetchedObjects 如果你有一个 Owner 对象,那么你不需要执行获取,如果你有一个 owner 对象,则返回 owner.dogs。 dogs 是一个 Set 所以你可能需要做 Array(owner.dogs) 如果你需要返回一个像 fetchedObjects 这样的数组 argumentArray 是一个数组。试试argumentArray: [owner] 【参考方案1】:

您使用了错误的 API。 argumentArray 用于多个占位符,其中数组中的项目数必须与占位符的数量匹配,例如

let parameters = [foo, bar, baz]
fetchRequest.predicate = NSPredicate(format: "foo = %@ AND bar = %@ AND baz = %@", argumentArray: parameters)

只需要搜索 owners contains owner,在安全解包后使用 self.owner 作为参数是一个非常糟糕的主意

if let owner = self.owner 
   fetchRequest.predicate = NSPredicate(format: "owners CONTAINS %@", owner)

【讨论】:

【参考方案2】:

正如@willeke 在 cmets 中所说,argumentArray: 参数需要一个数组。但您的谓词也需要稍有不同,因为关系是多对多的:

let fetchRequest: NSFetchRequest<Dog> = Dog.fetchRequest() //return all dogs by default
if let owner = self.owner 
    fetchRequest.predicate = NSPredicate(format: "ANY owner = %@", argumentArray: self.owner)

注意“ANY”修饰符。

【讨论】:

以上是关于对多关系的简单核心数据获取的主要内容,如果未能解决你的问题,请参考以下文章

从多对多关系中获取核心数据

核心数据对多关系 NSPredicate 来获取

如何在 IOS Swift 中获取核心数据中的多对多关系?

核心数据 - 在不触发错误的情况下获取对多关系的 objectID

核心数据多对多关系导致获取的结果控制器崩溃

获取“最新”单个实体的最简单 Fetch 请求 - 核心数据