如何解决从 Prisma 中的多对多表中获取元信息
我有这个表结构
注意 item_level
键
我需要完成的是拥有相同的物品,附加给许多玩家,但每个玩家都可以独立升级该物品。
这是我能想到的最简单的结构,用 sql 术语来说,连接表、选择字段并显示这些连接很容易。
我的问题是,我正在使用 Apollo graphql 和 Prisma ORM (v ^2.18.0),即使我可以获得每个玩家的物品,反之亦然-相反,我不知道如何包含该额外字段。
棱镜.schema
model Player {
id Int @id @default(id())
items ItemToPlayer[]
}
model Item {
id Int @id @default(id())
players ItemToPlayer[]
}
model ItemToPlayer {
player Player @relation(fields: [playerId],references: [id])
playerId Int
item Item @relation(fields: [itemId],references: [id])
itemId Int
itemLevel Int @default(0)
@@id([playerId,itemId])
}
typeDefs
const typeDefs = gql`
type Player {
id: ID!
items: [Item]
}
type Item {
id: ID!
players: [Player]
}
type ItemToPlayer {
playerId: Int!
itemId: Int!
itemLevel: Int!
}
`;
解析器
const resolvers = {
Player: {
items: (parent,args,context,info) => {
return context.db.item.findMany({
where: {
players: {
some: {
playerId: parent.id
}
}
},include: {
players: true
}
});
},},Item: {
players: (parent,info) => {
return context.db.player.findMany({
where: {
items: {
some: {
itemId: parent.id
}
}
},include: {
items: true
}
});
},Query: { /* ... */ },Mutation: { /* ... */ },};
这是我在查询玩家(包括他们的物品)时想要得到的结果
{
"data": {
"players": [
{
"id": 1
"items": [
{
"id": 1,"itemLevel": 2 // <--- This is missing
},{
"id": 2,"itemLevel": 3
},]
},{
"id": 2
"items": [
{
"id": 1,"itemLevel": 0 // same item (id: 1) has different level per player
}
]
},]
}
}
在 documentation 中,它将此描述为显式多对多关系,并提到
请注意,适用于 1-n 关系的相同规则(因为 Post↔ CategoriesOnPosts 和 Category ↔ CategoriesOnPosts 实际上都是 1-n-关系),这意味着关系的一侧需要 使用@relation 属性进行注释。
但它没有提供示例。
进一步研究 1-n-relations
和 @relation
,我发现的唯一示例是外键。
在 Internet 上搜索我发现其他人就不同的框架和 ORM 提出了相同的问题,但没有找到有关 Prisma 的任何信息。 (除非我错过了)
解决方法
我建议您将 typedef 更改为:
const typeDefs = gql`
type Player {
id: ID!
items: [ItemToPlayer]
}
type Item {
id: ID!
players: [ItemToPlayer]
}
type ItemToPlayer {
playerId: Int!
itemId: Int!
itemLevel: Int!
player: Player!
item: Item!
}
`;
然后您在 players
中的 Item
解析器将如下所示:
prisma.player.findMany({
where: {
items: {
some: {
itemId: parent.id,},include: {
items: { include: { item: true } },})
,
我按照@Ryan 在他的回答中建议的那样将 Item
更改为 ItemToPlayer
并更改了我的查询和解析器,从而设法获取了元数据。
新的 Item
解析器
Item: {
players: (parent,args,context,info) => {
return context.db.itemToPlayer.findMany({
where: {
itemId: parent.id
},include: {
item: true
}
});
},
我现在正在查询 ItemsToPlayers
表并返回一个 ItemToPlayer
类型,然后我可以从中查询 Item
CORRECT
query {
players {
id
items {
id
itemLevel
item {
id
}
}
}
}
WRONG
query {
players {
id
items {
id
itemLevel <--- This is wrong as itemLevel
does not exist in Item
}
}
}
结果
{
"data": {
"players": [
{
"id": 1
"items": [
{
"itemLevel": 2
"item": {
"id": 1,}
},{
"itemLevel": 0
"item": {
"id": 1,]
},]
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。