GORM select 预加载的特定列
GORM select certain column with preload
假设我有这些代表我的模型的结构
type QuestionHeader struct {
QuestionHeaderId int `gorm:"primaryKey;column:question_id" json:"question_id"`
LevelId int `gorm:"column:level_id" json:"level_id"`
SubjectId int `gorm:"column:subject_id" json:"subject_id"`
QuestionBody []QuestionBody
QuestionSolution []QuestionSolution
OtherColumn1A string
OtherColumn2A string
}
type QuestionBody struct {
QuestionBody int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
OtherColumn1B string
OtherColumn2B string
}
type QuestionSolution struct {
QuestionSolutionId int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
OtherColumn1C string
OtherColumn2c string
}
然后我想像这样使用预加载进行查询
qs.db().
Preload("QuestionHeader.QuestionBody", func(db *gorm.DB) *gorm.DB {
return db.Where("question_body.status = ?", 1)
// I only want to select certain column here
}).
Preload("QuestionHeader.QuestionSolution", func(db *gorm.DB) *gorm.DB {
return db.Where("question_solution.status = ?", 1)
// I only want to select certain column here
}).
Where("level_id = ?", 2).
Find(&questionHeaders) // I only want to select certain column here
但是该代码的问题是,我将 select 所有基于我的模型的列 属性
如果我只想 select 预加载特定列怎么办?
例如,我只想 select type
for QuestionBody
我知道您可以按照 docs 中的描述为 select 语句创建另一个结构,但是还有其他方法吗? 我不想为每个 select 语句创建一个结构
在LaravelEloquent中,你可以做类似
的事情
我想指出几个问题
- 您没有在
QuestionHeader
中为 QuestionBody
或 QuestionSolution
定义的 many2many
关联
- 在查询中您正在使用
status
列,但我似乎没有在 QuestionBody
或 QuestionSolution
中定义它们
- 在
QuestionBody
中将 QuestionBody
id 列重命名为 QuestionBodyId
根据积分变化如下:
type QuestionHeader struct {
QuestionHeaderId int `gorm:"primaryKey;column:question_id" json:"question_id"`
LevelId int `gorm:"column:level_id" json:"level_id"`
SubjectId int `gorm:"column:subject_id" json:"subject_id"`
QuestionBody []QuestionBody `gorm:"many2many:question_header_question_bodies;"`
QuestionSolution []QuestionSolution `gorm:"many2many:question_header_question_solutions;"`
OtherColumn1A string
OtherColumn2A string
}
type QuestionBody struct {
QuestionBodyId int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
Status uint8 `gorm:"column:status;default:0" json:"status"`
OtherColumn1B string
OtherColumn2B string
}
type QuestionSolution struct {
QuestionSolutionId int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
Status uint8 `gorm:"column:status;default:0" json:"status"`
OtherColumn1C string
OtherColumn2c string
}
var questionHeaders QuestionHeader
db.
Preload("QuestionBody", func(db *gorm.DB) *gorm.DB {
return db.Where("Status = ?", 1).Select("QuestionBodyId", "Value")
}).
Preload("QuestionSolution", func(db *gorm.DB) *gorm.DB {
return db.Where("Status = ?", 1).Select("QuestionSolutionId", "Value")
}).
Where("level_id = ?", 2).
Select("SubjectId").
Find(&questionHeaders)
}
在 Preload Select
中,我们必须包含 gorm
的唯一主键以唯一标识关联的结构切片
假设我有这些代表我的模型的结构
type QuestionHeader struct {
QuestionHeaderId int `gorm:"primaryKey;column:question_id" json:"question_id"`
LevelId int `gorm:"column:level_id" json:"level_id"`
SubjectId int `gorm:"column:subject_id" json:"subject_id"`
QuestionBody []QuestionBody
QuestionSolution []QuestionSolution
OtherColumn1A string
OtherColumn2A string
}
type QuestionBody struct {
QuestionBody int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
OtherColumn1B string
OtherColumn2B string
}
type QuestionSolution struct {
QuestionSolutionId int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
OtherColumn1C string
OtherColumn2c string
}
然后我想像这样使用预加载进行查询
qs.db().
Preload("QuestionHeader.QuestionBody", func(db *gorm.DB) *gorm.DB {
return db.Where("question_body.status = ?", 1)
// I only want to select certain column here
}).
Preload("QuestionHeader.QuestionSolution", func(db *gorm.DB) *gorm.DB {
return db.Where("question_solution.status = ?", 1)
// I only want to select certain column here
}).
Where("level_id = ?", 2).
Find(&questionHeaders) // I only want to select certain column here
但是该代码的问题是,我将 select 所有基于我的模型的列 属性
如果我只想 select 预加载特定列怎么办?
例如,我只想 select type
for QuestionBody
我知道您可以按照 docs 中的描述为 select 语句创建另一个结构,但是还有其他方法吗? 我不想为每个 select 语句创建一个结构
在LaravelEloquent中,你可以做类似
我想指出几个问题
- 您没有在
QuestionHeader
中为QuestionBody
或QuestionSolution
定义的 - 在查询中您正在使用
status
列,但我似乎没有在QuestionBody
或QuestionSolution
中定义它们
- 在
QuestionBody
中将
many2many
关联
QuestionBody
id 列重命名为 QuestionBodyId
根据积分变化如下:
type QuestionHeader struct {
QuestionHeaderId int `gorm:"primaryKey;column:question_id" json:"question_id"`
LevelId int `gorm:"column:level_id" json:"level_id"`
SubjectId int `gorm:"column:subject_id" json:"subject_id"`
QuestionBody []QuestionBody `gorm:"many2many:question_header_question_bodies;"`
QuestionSolution []QuestionSolution `gorm:"many2many:question_header_question_solutions;"`
OtherColumn1A string
OtherColumn2A string
}
type QuestionBody struct {
QuestionBodyId int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
Status uint8 `gorm:"column:status;default:0" json:"status"`
OtherColumn1B string
OtherColumn2B string
}
type QuestionSolution struct {
QuestionSolutionId int `gorm:"primaryKey;column:question_id" json:"question_id"`
Value string `gorm:"column:value" json:"value"`
Type string `gorm:"column:type" json:"type"`
Status uint8 `gorm:"column:status;default:0" json:"status"`
OtherColumn1C string
OtherColumn2c string
}
var questionHeaders QuestionHeader
db.
Preload("QuestionBody", func(db *gorm.DB) *gorm.DB {
return db.Where("Status = ?", 1).Select("QuestionBodyId", "Value")
}).
Preload("QuestionSolution", func(db *gorm.DB) *gorm.DB {
return db.Where("Status = ?", 1).Select("QuestionSolutionId", "Value")
}).
Where("level_id = ?", 2).
Select("SubjectId").
Find(&questionHeaders)
}
在 Preload Select
中,我们必须包含 gorm
的唯一主键以唯一标识关联的结构切片