英文:
Get nested object with one query
问题
我有以下模型:
type Instance struct {
gorm.Model
Name string `gorm:"unique;"`
UserID uint
GroupID uint
StackID uint
RequiredParameters []InstanceRequiredParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"requiredParameters,omitempty"`
OptionalParameters []InstanceOptionalParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"optionalParameters,omitempty"`
DeployLog string `gorm:"type:text"`
}
type InstanceRequiredParameter struct {
gorm.Model
InstanceID uint `gorm:"index:idx_instance_required_parameter,unique"`
StackRequiredParameterID uint `gorm:"index:idx_instance_required_parameter,unique"`
StackRequiredParameter StackRequiredParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
Value string
}
type InstanceOptionalParameter struct {
gorm.Model
InstanceID uint `gorm:"index:idx_instance_optional_parameter,unique"`
StackOptionalParameterID uint `gorm:"index:idx_instance_optional_parameter,unique"`
StackOptionalParameter StackOptionalParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
Value string
}
type StackRequiredParameter struct {
gorm.Model
StackID uint `gorm:"index:idx_name_required_parameter,unique"`
Name string `gorm:"index:idx_name_required_parameter,unique"`
}
type StackOptionalParameter struct {
gorm.Model
StackID uint `gorm:"index:idx_name_optional_parameter,unique"`
Name string `gorm:"index:idx_name_optional_parameter,unique"`
}
我正在尝试获取带有参数的实例,并且还需要检索StackRequiredParameter/StackOptionalParameter,因为我需要Name属性。
我可以使用以下函数来实现:
func (r instanceRepository) FindWithParametersById(id uint) (*model.Instance, error) {
var instance *model.Instance
err := r.db.First(&instance, id).Error
if err != nil {
return nil, err
}
var requiredParameters []model.InstanceRequiredParameter
err = r.db.
Where("instance_id = ?", id).
Preload("StackRequiredParameter").
Find(&requiredParameters).Error
if err != nil {
return nil, err
}
var optionalParameters []model.InstanceOptionalParameter
err = r.db.
Where("instance_id = ?", id).
Preload("StackOptionalParameter").
Find(&optionalParameters).Error
if err != nil {
return nil, err
}
instance.RequiredParameters = requiredParameters
instance.OptionalParameters = optionalParameters
return instance, nil
}
但这需要3个查询。有人可以建议使用Gorm只进行一次查询的方法吗?
英文:
I have the following model
type Instance struct {
gorm.Model
Name string `gorm:"unique;"`
UserID uint
GroupID uint
StackID uint
RequiredParameters []InstanceRequiredParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"requiredParameters,omitempty"`
OptionalParameters []InstanceOptionalParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"optionalParameters,omitempty"`
DeployLog string `gorm:"type:text"`
}
type InstanceRequiredParameter struct {
gorm.Model
InstanceID uint `gorm:"index:idx_instance_required_parameter,unique"`
StackRequiredParameterID uint `gorm:"index:idx_instance_required_parameter,unique"`
StackRequiredParameter StackRequiredParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
Value string
}
type InstanceOptionalParameter struct {
gorm.Model
InstanceID uint `gorm:"index:idx_instance_optional_parameter,unique"`
StackOptionalParameterID uint `gorm:"index:idx_instance_optional_parameter,unique"`
StackOptionalParameter StackOptionalParameter `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
Value string
}
type StackRequiredParameter struct {
gorm.Model
StackID uint `gorm:"index:idx_name_required_parameter,unique"`
Name string `gorm:"index:idx_name_required_parameter,unique"`
}
type StackOptionalParameter struct {
gorm.Model
StackID uint `gorm:"index:idx_name_optional_parameter,unique"`
Name string `gorm:"index:idx_name_optional_parameter,unique"`
}
I'm trying to get an instance with parameters and the StackRequiredParameter/StackOptionalParameter retrived as well since I need the Name property.
I can do it with the following function
func (r instanceRepository) FindWithParametersById(id uint) (*model.Instance, error) {
var instance *model.Instance
err := r.db.First(&instance, id).Error
if err != nil {
return nil, err
}
var requiredParameters []model.InstanceRequiredParameter
err = r.db.
Where("instance_id = ?", id).
Preload("StackRequiredParameter").
Find(&requiredParameters).Error
if err != nil {
return nil, err
}
var optionalParameters []model.InstanceOptionalParameter
err = r.db.
Where("instance_id = ?", id).
Preload("StackOptionalParameter").
Find(&optionalParameters).Error
if err != nil {
return nil, err
}
instance.RequiredParameters = requiredParameters
instance.OptionalParameters = optionalParameters
return instance, nil
}
But that takes 3 queries. Can anyone suggest a way to do it with just one query using Gorm?
答案1
得分: 0
你可以使用类似以下的代码来实现:
func (r instanceRepository) FindWithParametersById(id uint) (*model.Instance, error) {
var instance *model.Instance
err := r.db.Preload("RequiredParameters.StackRequiredParameter").Preload("OptionalParameters.StackOptionalParameter").First(&instance, id).Error
if err != nil {
return nil, err
}
return instance, nil
}
这段代码会在数据库中执行多个查询,因为每个Preload
调用都会运行一个单独的查询,但至少你不必编写那么多代码了。
英文:
You should be able to do that with something like this:
func (r instanceRepository) FindWithParametersById(id uint) (*model.Instance, error) {
var instance *model.Instance
err := r.db.Preload("RequiredParameters.StackRequiredParameter").Preload("OptionalParameters.StackOptionalParameter").First(&instance, id).Error
if err != nil {
return nil, err
}
return instance, nil
}
It will still perform multiple queries in your database, because each Preload
call runs a separate query, but at least you don't have to write all that code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论