PAYATHON 2026

如何在 SwiftUI View 中按关联对象筛选 SwiftData Query?

数据阿明

结论

不要在 #Predicate 中直接比较捕获的 Object 和 Location 模型实例。先读取它们的唯一字段,再让谓词比较关联模型上的标量属性。题目中的模型定义为 Object.name 和 Location.location 设置了唯一约束,可以用这两个字段定位记录。

原谓词直接把两个模型对象放进比较表达式:

let predicate = #Predicate<ObjAndLoc> {
    $0.object == self.object && $0.location == self.location
}

这样宏会尝试构造对象引用之间的 Equal 表达式。题目中的编译错误就出在这组谓词表达式上。

按唯一字段筛选

在 DataView 的初始化方法中先读取字符串值,再将它们用于谓词:

init(object: Object, location: Location) {
    self.object = object
    self.location = location

    let objectName = object.name
    let locationName = location.location

    let predicate = #Predicate<ObjAndLoc> {
        $0.object.name == objectName &&
        $0.location.location == locationName
    }

    _objAndLoc = Query(filter: predicate)
}

这里比较的是 ObjAndLoc 关联对象的唯一字段,而不是模型实例本身。根据题目给出的模型定义,name 和 location 都有唯一约束,因此可以分别标识目标 Object 和 Location。

检查查询结果

objAndLoc 是符合谓词的关联记录数组。如果只需要判断是否存在对应关系,可以检查数组是否为空:

let hasAssociation = !objAndLoc.isEmpty

请确认查询使用的 Object.name 和 Location.location 值确实唯一,并且 ObjAndLoc 中的关联属性名与谓词里的 object、location 一致。如果实际模型没有这些唯一字段,应改用能唯一标识记录的标量属性。

备注:内容仅供参考。