【问题标题】:Core Data: Extend Predicate to fetch related entities with special Attribute-Value核心数据:扩展谓词以获取具有特殊属性值的相关实体
【发布时间】:2014-08-09 12:32:07
【问题描述】:

我有 2 个实体(1 到多个),都有一个布尔标志“可见”

获取我使用的所有可见实体

request.predicate = NSPredicate(format:"visible != false")

这样我就可以将所有可见的 A 都填充为所有 B(包括不可见的)

问题:是否可以扩展谓词以获取所有可见的 A 仅填充 B 的所有可见实体? 还是我必须遍历所有实体?

谢谢!

[更新 1] 这是一些代码:

class A: NSManagedObject {
    @NSManaged var visible: NSNumber
    @NSManaged var relationShipToB: NSSet
}
class B: NSManagedObject {
    @NSManaged var visible: NSNumber
    @NSManaged var relationShipToA: NSManagedObject
}

[更新 2] 这就是我的解决方法的样子(在 Swift 中)

class A: NSManagedObject {
    @NSManaged var visible: NSNumber
    @NSManaged var relationShipToB: NSSet
    var visibleB:[B] {
        get {
            var result = [B]()
            for b in relationShipToB.allObjects as [B] {
                if(b.visible.boolValue) {
                    result.append(b)
                }
            }
            return result
        }
    }
}

[更新 3] 假设我们有以下实例:

A1 {
    visible = "true"
    toB = [B1, B2]
}

A2 {
    visible = "true"
    toB = [B3]
}

B1 {
    visible = "true"
}

B2 {
    visible = "false"
}

B3 {
    visible = "false"
}

预期结果:

A1 [B1]
A2 []

由于我的请求,我想获得 A1A2(两者都是可见的)。 但是作为一个包含 A1.toBonly想要有 B1B2 是不可见的) 而 A2.toB 将是 emty,因为 B3 是不可见的。

【问题讨论】:

  • 请用 A 类和 B 类代码更新帖子。
  • 有可能,您应该使用 ALL 运算符。由于缺少代码,目前很难给您现成的答案。
  • 如果解决方法解决了问题,请将其作为答案发布并接受!

标签: core-data swift nspredicate


【解决方案1】:
request.predicate = NSPredicate(format:"visible = true AND ALL relationShipToB.visible = true")

【讨论】:

  • 这也不起作用。我不能使用 ALL-Operator(不知道为什么)。出现以下错误:“由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'Unsupported predicate visible == 1 AND ALL toB.visible == 1'”
  • 同样的错误。单个等号将更改为双等号。此外,给定参数“true”或“yes”会自动更改为“1”。
【解决方案2】:

你可以试试下面的代码...

request.predicate = NSPredicate(format:"visible != false && ANY toB.visible != false")

...其中toB 是A 和B 之间的一对多关系的名称。

编辑

使用 NSExpression 子查询表达式 (see Apple documentation),您可以像这样编写前面谓词的等价物:

fetchRequest.predicate = NSPredicate(format: "visible != false && (SUBQUERY(toB, $x, $x.visible != false).@count != 0)")

这两个谓词将允许您找到可见的 A 文件,其中至少有一个可见的相关 B 管理对象。

如果你想获取只有可见的相关B managedObjects的A managedObjects,你可以使用@Shmidt给我们的谓词:

request.predicate = NSPredicate(format:"visible != false && ALL toB.visible != false")

但问题在于,基于 SQLite(NSSQLiteStoreType Persistent Store Type)的 Core Data 项目不能使用包含“ALL”的谓词:它会产生一个编译时错误,就像你得到的那样(see this old post from Melissa Turner)。

幸运的是,再次使用 NSExpression 子查询表达式,您可以编写一个(丑陋的)与前面的谓词等效的方法,该谓词将适用于基于 Core Data SQLite 的项目:

fetchRequest.predicate = NSPredicate(format: "visible != false && (SUBQUERY(toB, $x, $x.visible != false).@count == toB.@count)")

【讨论】:

  • 谢谢,但这不起作用,因为它是一对多的关系。出现以下错误:“由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'此处不允许对多键'”
  • 编辑了我的答案:我忘记了谓词中的“ANY”。
  • 查看我的编辑#2以获得更完整的答案。
  • 哇,现在变得复杂了 :-) 但我想,我仍然想要一些不同的东西。查看我更新的问题
  • 当你做一个 fetchRequest(使用任何谓词)时,这个请求的结果是一个相同类型的 managedObjects 的 NSArray。因此,如果您对 A managedObjects 执行 fetchRequest,则此 fetchRequest 的结果将是 A managedObjects 的 NSArray(不是 A 和 B 混合的 managedObjects 数组)。如果您想要的实际上是让所有 B 可见对象都具有可见的 toA 关系,则您必须对 B 实体执行 fetchRequest。告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2011-10-24
  • 1970-01-01
相关资源
最近更新 更多