【问题标题】:Combining 2 values into a NSPredicate将 2 个值组合成一个 NSPredicate
【发布时间】:2017-05-10 00:32:24
【问题描述】:

我正在尝试执行一个 fetch 请求来检查两件事。

这是我的数据:

人 - 实体 声明 - 实体 Person 实体与 To Many 的语句有关系。语句实体有一个名为 amountOwed 的属性。这是我要在谓词中检查的属性。

编辑 我想做的是这个。 检查我所有的 Persons 实体的名称,比如说 Bob。

一旦我找到 Bob 实体,我想检查他的所有 Statement 实体是否有一个名为 amountOwed 的属性,看看它是大于还是小于 0。

  1. 检查人员实体中的名称。当该名称匹配时,使用该实体。
  2. 检查 Statement 实体中的 amountOwed 是大于还是小于 0。

这就是我一直在努力的工作。

let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
fetchRequest.predicate = NSPredicate(format:"name == %@ AND @statement.amountOwed >= 0", personName))
let sort = NSSortDescriptor(key: #keyPath(Person.name), ascending: true)
fetchRequest.sortDescriptors = [sort]
positiveFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.managedContext, sectionNameKeyPath: nil, cacheName: nil)

do {
    try positiveFetchedResultsController.performFetch()
} catch let error as NSError{
    print("Fetching error: \(error), \(error.userInfo)")
}

我收到此错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'

我在这里找到了 AND 方法:using AND link

编辑

【问题讨论】:

  • 为什么没有人阅读documentation? ;-)
  • 错误是“这里不允许对多键。”。您的谓词中只有一对多键:“statement.amountOwed >= 0”。所以错误是说“每个人可以有很多报表 - 我应该使用哪一个?具有最大金额的那个?或最低金额?或者任何声明上的金额?或者检查所有报表上的金额?或者(如我认为您的意思)将所有相关语句的金额相加。如果是最后一个,请使用fetchRequest.predicate = NSPredicate(format:"name == %@ AND statement.@sum.amountOwed &gt;= 0", personName)
  • 我正在尝试显示每个人的所有语句,并将它们划分为负数和正数,然后在 tableView 的一部分中显示每个 FRC。这有意义吗?
  • 为了澄清,您的表格视图将显示单个 Person 的语句。每行将代表一个语句(针对那个人)。将有两个部分;一个显示带有 +ve amountOwed 的 Statements,另一个显示带有 -ve amountOwed 的 Statements。如果正确,您希望这些行的顺序是什么?
  • 没错。这些行可以是任何顺序。如果从最大到最小显示它们更容易,那很好。重要的是表格视图的每个部分都能正确显示。一节用于正金额,一节用于负金额。

标签: ios xcode core-data swift3 nspredicate


【解决方案1】:

您应该构建 FRC 以获取 Statement 对象,而不是 Person 对象:

let fetchRequest: NSFetchRequest<Statement> = Statement.fetchRequest()

假设statement 关系有一个名为person 的反向(一对一)关系,那么您可以使用以下谓词确保您只获取与具有给定条件的人相关的具有正向amountOwed 的语句名称:

fetchRequest.predicate = NSPredicate(format:"person.name == %@ AND amountOwed >= 0", personName)

(对于否定的 amountOwed 也是如此)。指定排序描述符以获得您想要的任何排序顺序。然后,您的 FRC 的 fetchedObjects 数组将包含 Statement 对象,您可以使用这些对象填充表格视图:第 0 节的正 FRC 和第 1 节的负 FRC(反之亦然)。

注意。因为您正在获取 Statement 对象,所以只需一个 FRC 即可实现您想要的 - 但前提是您对按 amountOwed (升序或降序)排序的语句感到满意。如果您想这样做,我可以提供更多详细信息。

【讨论】:

  • 您好,我尝试自己实现您的想法。它不起作用,所以我非常感谢您的想法的更多细节。它似乎没有在谓词中找到具有名称的实体。
  • 我将在今天晚些时候更新我的答案 - 同时,请您发布您的数据模型的图片吗?谢谢。
  • 让我知道您是否要从我的数据模型中寻找。
  • 我的 fetch 请求返回 0,即使我知道有一个已保存。
  • 好的。删除谓词,运行 fetch 然后打印结果。检查您获取的语句的“person”属性,然后检查“person.name”。
【解决方案2】:

试试这个:

NSPredicate(format:"name == %@ AND statement.@amountOwed >= 0", personName)

AND 必须是您附加的示例字符串的一部分...

【讨论】:

  • 属性amountOwed前面需要@吗?应该是:fetchRequest.predicate = NSPredicate(format:"name == %@ AND statement.amountOwed &gt;= 0",personName)。当我尝试任何一种方式时,都会出现错误。由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“此处不允许多对多键”
  • 它是你代码中的变量吗?像这样尝试 NSPredicate(format:"name == %@ AND %@ >= 0", personName, statement.amountOwed)
  • no 欠款是 Statement 实体的属性。我正在获取的 Person 实体可以有多个 Statement 实体链接到它。所以我试图通过名字获取一个人,然后查看他们所有的 Statement 实体。
  • 我没有这方面的经验,但 AND 必须在格式字符串内。祝你好运
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
  • 2013-04-19
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多