【问题标题】:Get nested object with one query一次查询获取嵌套对象
【发布时间】:2021-06-09 11:59:47
【问题描述】:

我有以下型号

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"`
}

我正在尝试获取一个带有参数的实例,并且由于我需要 Name 属性,因此也检索了 ​​StackRequiredParameter/StackOptionalParameter。

我可以用下面的函数做到这一点

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 仅通过一个查询来完成此操作的方法吗?

【问题讨论】:

    标签: go go-gorm


    【解决方案1】:

    您应该可以通过以下方式做到这一点:

    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 调用都会运行一个单独的查询,但至少您不必编写所有代码。

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 1970-01-01
      • 2016-06-21
      • 2021-10-02
      • 2013-06-03
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多