【问题标题】:How do I count relationships with a particular column value from an NSFetchRequest?如何计算与 NSFetchRequest 中特定列值的关系?
【发布时间】:2020-03-07 21:56:45
【问题描述】:

我目前有 2 个实体:

  • 列表
  • 项目

这是一对多的关系,其中一个 List 可以有多个 Item。

项目有一个名为completed 的列。

我想从我的 NSFetchRequest 中获取 Lists completed Items 的计数。

我知道我可以简单地执行List.Items.count 来获取所有列表项的计数,但我也不知道如何获取completed 项的计数。

如何计算与 NSFetchRequest 中的特定列值的关系,甚至是 List.Items.count 的某种类型的过滤器/位置?

编辑

我不得不将 List 重命名为 MyList 并将 Item 重命名为 MyItem

  • MyList -> MyItem 在 Core Data 中是一对多的(所以我可以在获取的结果中使用 myList.myItems)
  • MyItem -> MyList 在 Core Data 中是多对一的(因此我可以在获取的结果中使用 myItem.myList)

这是我获取数据的方式。首先我使用一个扩展:

extension MyList {
    static func getAllMyLists() -> NSFetchRequest<MyList> {
        let request: NSFetchRequest<MyList> = MyList.fetchRequest()
        let sortDescriptor = NSSortDescriptor(key: "sortOrder", ascending: true)

        request.sortDescriptors = [sortDescriptor]

        return request
    }
}

然后我在视图结构中使用@FetchRequest

@FetchRequest(fetchRequest: MyList.getAllMyLists()) var myLists: FetchedResults<MyList>

就像我说的那样,我不知道如何添加我想要的谓词,以便结果包括 completed MyItems 的计数...我在回答中使用了一种糟糕的方法,没有使用由于缺乏知识,获取请求的全部潜力。

【问题讨论】:

  • 使用谓词..
  • 关于什么?一种表达?就像我说的那样,我不知道该怎么做。
  • 不清楚您对已完成列表的意思是什么?它是一个所有项目都标记为已完成的列表。请添加您想要做的示例。
  • 项目有一个名为completed 的列,它是一个布尔值。我想对每个列表中的completed 项目进行计数。这是我在核心数据中建立的一对多关系...
  • 如果你只想计算完成,那么你可以在你的代码中使用filter,比如lists.items.filter { $0.completed }.count

标签: ios swift xcode


【解决方案1】:

dahiya_boy 和 Joakim 都在 cmets 中,我必须使用 NSPredicatefiltered

let completedPredicate: NSPredicate = NSPredicate(format: "completed == true")
let completedCount = List.Items.filtered(using: completedPredicate).count

【讨论】:

  • 不,cmets 的意思是在 fetch 请求中添加谓词。数据库中的过滤效率更高。
  • 您能否发布一个示例作为我如何做到这一点的答案,我会接受吗?
  • 首先可以发布您的代码以获取数据。请编辑问题。
【解决方案2】:

有两种方式:

  • 如果您有对 List 对象的引用,只需过滤 NSSet 关系

    let numberOfCompletedItems = (list.items as! Set<MyItem>).filter{$0.completed}.count
    

    如果将一对多关系声明为原生Set&lt;MyItem&gt;,则可以避免强制类型转换

  • 否则获取项目并将谓词添加到获取请求中

    • "TheList" 是列表的名称。如果没有 name 属性,请使用独特的属性。
    • context 是对托管对象上下文的引用
    • 假设listMyItem之间存在反比关系

      let listName = "TheList" 
      let request: NSFetchRequest<MyItem> = MyItem.fetchRequest()
      request.predicate = NSPredicate(format: "list.name == %@ AND completed == true", listName)
      do {
         let completedItems = try context.fetch(request)
         let numberOfCompletedItems = completedItems.count
      } catch { print(error) }
      

请按照以小写字母开头的命名约定命名变量

【讨论】:

  • 有没有办法在单个获取请求中获取所有 myLists 及其 completed myItem 计数?我正在阅读有关表达式的内容,但无法掌握如何对表达式本身进行谓词...我想吐出ForEach 中的所有列表并包括completed myItem 每个计数...
  • 简单方法:获取所有已完成项(删除谓词格式中的list.name == %@)并将数组按listDictionary(grouping:by:)分组。 NSExpression 也是可能的,但这有点复杂。
猜你喜欢
  • 1970-01-01
  • 2018-09-11
  • 2019-02-12
  • 1970-01-01
  • 2012-02-23
  • 2021-06-27
  • 2020-08-02
  • 1970-01-01
  • 2022-01-02
相关资源
最近更新 更多