首页 > 解决方案 > 一对多关联

问题描述

我在 GORM 中遇到了一对多关联的问题。我有这两种结构,我想了解一名患者的完整病史。这是我的示例代码:

type Patient struct {
    gorm.Model
    Prenom     string       `json:"prenom" gorm:"column:patient_prenom"`
    Nom        string       `json:"nom" gorm:"column:patient_nom"`
    Genre      string       `json:"genre" gorm:"column:patient_genre"`
    Naissance  string       `json:"naissance" gorm:"column:patient_naissance"`
    Historique []Historique `gorm:"ForeignKey:Fk_patient_id"`
}
type Historique struct {
    Fk_patient_id        string
    Date_consultation    string
    Fk_maladie_id        uint
    Fk_compte_medecin_id uint
    Patient              Patient
}

func GetPatientWithDiseases(id uint) (*Patient, error) {
    patient := &Patient{}
    //The line right there works so i can retrieve without the history
    //err := GetDB().Find(patient, id).Error
    db := GetDB().Preload("tt_historique").Find(patient)
    err := db.Error

    if err != nil {
        return nil, err
    }
    return patient, nil
}

其中“Historique”使用患者的外键(Fk_patient_id),而 Historique []Historique 是查询后应该在 Patient 结构中结束的每个 Historique 的列表。

但是我得到这个错误can't preload field tt_historique for models.Patient。我已经尝试了多种语法,这些语法是我在 Internet 上的结构中的 gorm 规范中找到的,但没有任何效果。我只使用 GO 开发了 3 天,而 GORM 是我的第一个 ORM,所以也许我错过了一些非常明显的东西。

标签: goone-to-manyhas-manygo-gorm

解决方案


根据tt_historique您的表名的假设,您需要在这里处理几件事。

按照惯例,go-gorm 在构建 SQL 查询时使用复数的蛇案例结构名称作为数据库表。在您的情况下,要预加载该Historique []Historique字段,它会查找该historiques表。

要覆盖它,您需要实现Tabler接口:

type Patient struct {
    gorm.Model
    Prenom     string       `json:"prenom" gorm:"column:patient_prenom"`
    Nom        string       `json:"nom" gorm:"column:patient_nom"`
    Genre      string       `json:"genre" gorm:"column:patient_genre"`
    Naissance  string       `json:"naissance" gorm:"column:patient_naissance"`
    Historique []Historique `gorm:"foreignKey:Fk_patient_id"`
}
type Historique struct {
    Fk_patient_id        string
    Date_consultation    string
    Fk_maladie_id        uint
    Fk_compte_medecin_id uint
    Patient              Patient
}

func (Historique) TableName() string {
  return "tt_historique"
}

然后,您的查询将如下所示:

db := GetDB().Preload("Historique").Find(patient)

推荐阅读