在 gorm 中使用 Preload 和 Join
using Preload and Join in gorm
假设我有这 3 个结构
type Question struct {
gorm.Model
Id *uint64 `json:"id" gorm:"column=id;primaryKey;autoIncrement"`
Name string `json:"name" gorm:"unique"`
SkillId *uint64 `json:"skill_id"`
TestQuestions []TestQuestion `json:"test_questions"`
}
type Skill struct {
gorm.Model
SkillName string `json:"skill_name"`
Question []Question
}
type TestQuestion struct {
gorm.Model
QuestionId uint64 `json:"question_id"`
TestId uint64 `json:"test_id"`
}
我想 select 所有问题,对于每个问题,我想 select 该问题的技能名称而不是技能 ID,我想预加载 TestQuestion
我试图让这个结构来存储我的结果
type struct QuestionResponse(
SkillName string
Name string `json:"name"`
TestQuestions TestQuestion `json:"test_questions"`
}
我试过这个查询
db.Table("questions").Preload("TestQuestions").
Joins("inner join skills on questions.skill_id = skills.id").
Select("questions.name,skills.skill_name, questions.difficulty, questions.max_points, questions.type, questions.expected_time, questions.question_text,questions.file_read_me").
Find(&question)
但我收到此错误“为结构 github.com...../models.QuestionResponse 的字段 TestQuestions 找到了无效字段:为关系定义一个有效的外键或实现 Valuer/Scanner 界面”
任何解决方案?
首先我建议你在你的结构中使用 gorm 标签,其次 gorm.Model 已经给了我们一些基本字段,比如作为主键的 ID 等 (https://gorm.io/docs/models.html#gorm-Model)
但这是节省时间的结构:
// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
我不明白你想用你的结构做什么,所以我建议你看看这个:,并更多地考虑你的数据库的关系。
基本:(感谢 https://whosebug.com/users/415628/ezequiel-muns)
- foreignKey 应该命名连接到外部实体的模型本地键字段。
- 引用应命名外国实体的主键或唯一键。
请记住,.Preload("some stuff") 将基本执行 select (*),以满足数据库中结构的结构(例如来自用户的订单),因此有时在嵌入中拥有您想要的字段并为该 select 拥有一个独特的结构比“适合所有”结构更好。
Gorm 有一些像 Omit() 这样的函数可以在插入或更新中省略一个字段。
假设我有这 3 个结构
type Question struct {
gorm.Model
Id *uint64 `json:"id" gorm:"column=id;primaryKey;autoIncrement"`
Name string `json:"name" gorm:"unique"`
SkillId *uint64 `json:"skill_id"`
TestQuestions []TestQuestion `json:"test_questions"`
}
type Skill struct {
gorm.Model
SkillName string `json:"skill_name"`
Question []Question
}
type TestQuestion struct {
gorm.Model
QuestionId uint64 `json:"question_id"`
TestId uint64 `json:"test_id"`
}
我想 select 所有问题,对于每个问题,我想 select 该问题的技能名称而不是技能 ID,我想预加载 TestQuestion 我试图让这个结构来存储我的结果
type struct QuestionResponse(
SkillName string
Name string `json:"name"`
TestQuestions TestQuestion `json:"test_questions"`
}
我试过这个查询
db.Table("questions").Preload("TestQuestions").
Joins("inner join skills on questions.skill_id = skills.id").
Select("questions.name,skills.skill_name, questions.difficulty, questions.max_points, questions.type, questions.expected_time, questions.question_text,questions.file_read_me").
Find(&question)
但我收到此错误“为结构 github.com...../models.QuestionResponse 的字段 TestQuestions 找到了无效字段:为关系定义一个有效的外键或实现 Valuer/Scanner 界面” 任何解决方案?
首先我建议你在你的结构中使用 gorm 标签,其次 gorm.Model 已经给了我们一些基本字段,比如作为主键的 ID 等 (https://gorm.io/docs/models.html#gorm-Model) 但这是节省时间的结构:
// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
我不明白你想用你的结构做什么,所以我建议你看看这个:
基本:(感谢 https://whosebug.com/users/415628/ezequiel-muns)
- foreignKey 应该命名连接到外部实体的模型本地键字段。
- 引用应命名外国实体的主键或唯一键。
请记住,.Preload("some stuff") 将基本执行 select (*),以满足数据库中结构的结构(例如来自用户的订单),因此有时在嵌入中拥有您想要的字段并为该 select 拥有一个独特的结构比“适合所有”结构更好。 Gorm 有一些像 Omit() 这样的函数可以在插入或更新中省略一个字段。