【问题标题】:core data how to filter (NSPredicate) including a relationship requirement and given the relationship object? [closed]核心数据如何过滤(NSPredicate)包括一个关系需求和给定的关系对象? [关闭]
【发布时间】:2023-03-21 20:46:01
【问题描述】:

我将如何过滤(构造一个 NSPredicate)以获取以下内容。

  • 拥有 SCHOOL 和 PERSON 实体
  • 一对多关系,即一个人有一个学校,学校有很多人
  • 过滤器方法的输入是 (a) 人员姓名(例如所有人的名字都是“Tom”),以及 (b) School 本身的管理对象。
  • 就本问题而言,假设 School 没有唯一属性

那么我的困惑/观察是:

  • 我已经拥有 School 托管对象本身,但是在创建谓词时不确定如何使用它?
  • 但是,如果我创建了 NSPredicate,在任何情况下我如何创建与 SCHOOL 的关系,因为我让 Core Data 执行此操作时自己没有链接它们的 ID(标识符)?

首选是 SWIFT(但是如果有人知道 Objective-C 也可能对我有帮助)。所以我再次尝试做的是:

  • 获取所有 PERSON 对象,其中 first name = "xxx",并且它们与以下 SCHOOL 托管对象相关联。

【问题讨论】:

  • 学校有独特的名称或任何其他独特的财产价值吗?如果是,您可以将其用于谓词。
  • 显示示例数据和所需结果以及您迄今为止尝试的代码及其产生的错误/结果
  • 目前 SCHOOL 中没有唯一名称 - 希望有一种方法可以创建这样的谓词而不必这样做...?
  • 没有显示错误的代码,因为我不确定如何构造代码
  • 但是您如何识别/区分学校呢?在为某人分配学校时,您已经需要它了。

标签: ios swift core-data relationship nspredicate


【解决方案1】:

谓词将是您所期望的。

NSPredicate(format: "name = %@ && school = %@", "Tom", school)

但是,您可以通过使用另一个方向的关系和过滤器,在没有谓词的情况下找到该人。

let tom = school.persons.filter { $0.name == "Tom" }.first

(您可能需要将 NSSet 转换为 Set<Person>)。

【讨论】:

  • 看来你选错了答案。 :-(。最好避免使用谓词。
  • 哦,没有考虑到这一点 - 你这么说是因为这样的代码更简单吗?还是有别的?
  • 是的,代码少了很多,更像“Swift”,你让 Core Data 处理数据库层,同时专注于对象图。实际上,您不必关心设置获取请求。
  • 除非我遗漏了什么,否则这是一个完全不涉及 Core Data 的纯 Swift 解决方案。您只是将与 School 关联的每个人都记入内存,然后手动检查每个人是否符合标准。这几乎总是错误的解决方案。
  • 看起来像这样,但您过滤NSManagedObject 的事实仍然会提高效率。您可以在 100.000 条记录上进行测试,而不会出现延迟或内存峰值。
【解决方案2】:

假设以下模型:

.. 并且你想使用NSPredicate ..你可以试试这样的:

func searchSchool(school: School, firstName: String) -> [Person] {

    let request = NSFetchRequest(entityName: "Person")
    let predicate = NSPredicate(format: "school == %@ && firstName == %@", school, firstName)
    request.predicate = predicate

    // we will perform the request on the context associated with the School NSManagedObject
    guard let context = school.managedObjectContext else {
        print("provided School managed object is not associated with a managed object context")
        return []
    }

    do {
        return try context.executeFetchRequest(request) as? [Person] ?? []
    } catch {
        return []
    }

}

但是,不要忘记其他选项(如遍历关系并使用@Mundi 建议的filter

【讨论】:

  • 非常感谢 - 不确定我应该选择哪个答案,但注意到您的答案在代码中给出了整个上下文......
  • 上面的数据模型图中有一个错误(to-many in wrong direction)。此外,提供的方法不适合在表格中显示(应该是获取结果控制器)。
  • 模型图对我来说看起来不错...School 可以有 many Persons(to-many,由 @987654328 的箭头上的双端表示@到Person); Personone 学校(一对一,由从 PersonSchool 的箭头上的单端表示)。使用上面的确切模型,生成的 NSManagedObject 子类对于 School 中的 persons 属性的 NSSet 是正确的。我也是 NSFetchedResultsController 的忠实粉丝,喜欢从 CoreData 中提取表格。在 OP 问题中没有提到使用表格。代码试图通过一个例子来帮助 OP。为您的答案投票,这样您就不会觉得被骗了。
猜你喜欢
  • 2011-02-01
  • 2011-04-10
  • 2013-05-03
  • 2015-08-24
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
相关资源
最近更新 更多