核心数据:扩展谓词以获取具有特殊属性值的相关实体

时间:2014-08-09 12:32:08

标签: core-data swift nspredicate

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

要获取A的所有可见实体,请使用

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 []

根据我的要求,我想获得 A1 A2 (两者都可见)。 但是作为包含 A1.toB 想要 B1 B2 不可见) 并且 A2.toB 将是emty,因为 B3 不可见。

2 个答案:

答案 0 :(得分:0)

您可以尝试以下代码......

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)")

这两个谓词将允许您查找至少具有一个可见相关B托管对象的可见A文件。

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

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

但问题是基于SQLite的Core Data项目(NSSQLiteStoreType持久存储类型)不能使用包含“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)")

答案 1 :(得分:0)

request.predicate = NSPredicate(format:"visible = true AND ALL relationShipToB.visible = true")