在 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() 这样的函数可以在插入或更新中省略一个字段。