XCode 15 beta 6.
Xcode15测试版6。
Just want to do a very simple Query Predicate where the relationship model matches:
我只想在关系模型匹配的地方执行一个非常简单的查询谓词:
@Query(
filter: #Predicate<Piece> {
$0.artist == selectedArtist
},
sort: [
SortDescriptor(\Piece.age, order: .reverse)
]
) var pieces: [Piece]
and I'm receiving error:
我收到错误消息:
Cannot convert value of type 'PredicateExpressions.Equal<PredicateExpressions.KeyPath<PredicateExpressions.Variable, Artist>, PredicateExpressions.Value>' to closure result type 'any StandardPredicateExpression'
I also tried .id and .persistentModelId on the artist but no luck.
我还在艺术家身上尝试了.id和.sistentModelID,但没有成功。
This seems like the most basic predicate use case so I'd be shocked if it's not supported. Any ideas what i'm missing?
这似乎是最基本的谓词用例,所以如果它不受支持,我会感到震惊。知道我错过了什么吗?
My models are basic:
我的模型是基本的:
@Model
final class Piece {
var age: Int
var artist: Artist
}
And
和
@Model
final class Artist {
var name: String
@Relationship(
deleteRule: .cascade,
inverse: \Piece.artist
)
var pieces: [Piece]?
}
更多回答
I don’t think you have missed anything, this must be a bug. And you are not alone
我不认为你错过了什么,这一定是个错误。你并不孤单
优秀答案推荐
You gave me an idea and it worked !!!
你给了我一个主意,它奏效了!
Considering that you can't use another model in the predicate, then first set a variable with the persistentModelID and use that variable in the predicate.
考虑到不能在谓词中使用另一个模型,那么首先用persistentModelID设置一个变量,并在谓词中使用该变量。
I was having the same problem and this worked for me. Of course you need to set the query in your init()
我也有同样的问题,这对我很管用。当然,您需要在init()中设置查询
EDIT: I added part of the code that could be helpful.
编辑:我添加了可能会有帮助的部分代码。
@Query private var homes: [Home]
init(session: Session) {
let id = session.persistentModelID
let predicate = #Predicate<Home> { home in
home.session?.persistentModelID == id
}
_homes = Query(filter: predicate, sort: [SortDescriptor(\.timestamp)] )
}
Per answer here, it seems like #Predicate
will not let you use another @Model
in the code block. Based on this logic, I don't think there's a way to do this as part of @Query
without jumping through a bunch of hoops.
根据这里的答案,似乎#Predicate不会让你在代码块中使用另一个@Model。基于这种逻辑,我不认为有一种方法可以作为@Query的一部分做到这一点,而不需要跳过一堆箍。
If your dataset is relatively small, the best suggestion is to filter it yourself:
如果您的数据集相对较小,最好的建议是自己对其进行过滤:
@Query(
sort: [
SortDescriptor(\Piece.age, order: .reverse)
]
) var pieces: [Piece]
private var filteredPieces: [Piece] {
return pieces.compactMap { piece in
guard let artist = piece.artist else {
return nil
}
return artist == selectedArtist ? piece : nil
}
}
and you can use your filtered data below:
你可以在下面使用你的过滤数据:
var body: some View {
List {
ForEach(filteredItems) { item in
//show filtered stuff
}
}
}
更多回答
Can you add some code snippets? This is a great suggestion. I didn't know it was possible to manipulate the query at run-time like this.
你能添加一些代码片段吗?这是一个很好的建议。我不知道可以在这样的运行时操作查询。
Done. I copied part of my code (names were modified to protect the innocents, lol)
好了。我复制了我的部分代码(名字被修改是为了保护无辜者,呵呵)
我是一名优秀的程序员,十分优秀!