Gorm查询自定义连接额外列

huangapple go评论83阅读模式
英文:

Gorm Query Customized Join Extra Column

问题

我正在尝试从Gorm的many2many关系中获取额外的列。示例:

  1. Part
type Part struct {
    Id   uint
    Name string
}
  1. Diagram
type Diagram struct {
    Id    uint
    Name  string
    Parts []Part `gorm:"many2many:diagram_parts;"`
}
  1. DiagramPart
type DiagramPart struct {
    DiagramId         uint   `gorm:"primaryKey"`
    PartId            uint   `gorm:"primaryKey"`
    PartDiagramNumber int
    PartNumber        string
    PartDescription   string
}

这是我尝试在Parts中检索PartNumber和PartDescription的代码:

diagram := &Diagram{}
db := s.db.Where("id = ?", 1).
    Preload("Parts", func(db *gorm.DB) *gorm.DB {
        return db.Select("parts.*, diagram_parts.part_number, diagram_parts.part_description").
            Joins("left join diagram_parts on diagram_parts.part_id = parts.id")
    }).
    First(diagram)

不幸的是,我无法检索到part_number和part_description。我该如何解决这个问题?

英文:

I am trying to get extra columns from a many2many relationships on Gorm. Example

  1. Part
type Part struct {
    Id unit
    Name string
 }
  1. Diagram
type Diagram struct {
    Id unit
    Name string
    Parts []Part `gorm:"many2many:diagram_parts;"`
 }
  1. DiagramPart
type DiagramPart struct{
    DiagramId         uint `gorm:"primaryKey"`
	PartId            uint `gorm:"primaryKey"`
	PartDiagramNumber int
	PartNumber        string
	PartDescription   string
}

This is what I have done trying to retrieve PartNumber and PartDescription in Parts.

diagram := &Diagram{}
db := s.db.Where("id = ?", 1).
		Preload("Parts", func(db *gorm.DB) *gorm.DB {
			return db.Select("parts.*, diagram_parts.part_number, diagram_parts.part_description").
				Joins("left join diagram_parts on diagram_parts.part_id = parts.id")
		}).
		First(diagram)

Unfortunately, I am not able to retrieve part_number, part_description. How should I go about it?

答案1

得分: 4

你可以在Part结构体或Diagram结构体上添加PartNumberPartDescription字段,然后在这些字段上添加gorm:"-:migration->"标签,以忽略迁移并将其设置为只读模式。但在你的情况下,你可以将其添加到Part结构体中,因为你已经预加载了它。

参考链接:https://gorm.io/docs/models.html#Field-Level-Permission

以下是示例代码:

package main

import (
	"fmt"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

type Part struct {
	Id              uint   `gorm:"primaryKey"`
	Name            string
	PartNumber      string `gorm:"-:migration->"`
	PartDescription string `gorm:"-:migration->"`
}

type Diagram struct {
	Id              uint   `gorm:"primaryKey"`
	Name            string
	Parts           []Part `gorm:"many2many:diagram_parts;"`
	// PartNumber      string `gorm:"-:migration->"`
	// PartDescription string `gorm:"-:migration->"`
}

type DiagramPart struct {
	DiagramId         uint   `gorm:"primaryKey"`
	PartId            uint   `gorm:"primaryKey"`
	PartDiagramNumber int
	PartNumber        string
	PartDescription   string
}

func main() {
	db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}
	db.AutoMigrate(&Diagram{}, &Part{}, &DiagramPart{})
	diagram := &Diagram{}
	err = db.Debug().Where("id = ?", 1).
		// Select("diagrams.*, diagram_parts.part_number, diagram_parts.part_description").
		Preload("Parts", func(db *gorm.DB) *gorm.DB {
			return db.Select("parts.*, diagram_parts.part_number, diagram_parts.part_description").
				Joins("left join diagram_parts on diagram_parts.part_id = parts.id")
		}).
		// Joins("left join diagram_parts on diagram_parts.diagram_id = diagrams.id").
		First(diagram).Error
	if err != nil {
		panic(err)
	}

	fmt.Printf("diagram: %v\n", diagram)
	fmt.Println("part number:", diagram.Parts[0].PartNumber)
}

英文:

You can add field PartNumber and PartDescription on struct Part OR Diagram, then add tag gorm:"-:migration;->" on than fields to ignore migration and to readonly mode. But on your situation, you can add it in struct Part because you already preload it.

source: https://gorm.io/docs/models.html#Field-Level-Permission

here's the example:

package main

import (
	"fmt"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

type Part struct {
	Id              uint `gorm:"primaryKey"`
	Name            string
	PartNumber      string `gorm:"-:migration;->"`
	PartDescription string `gorm:"-:migration;->"`
}

type Diagram struct {
	Id              uint `gorm:"primaryKey"`
	Name            string
	Parts           []Part `gorm:"many2many:diagram_parts;"`
	// PartNumber      string `gorm:"-:migration;->"`
	// PartDescription string `gorm:"-:migration;->"`
}

type DiagramPart struct {
	DiagramId         uint `gorm:"primaryKey"`
	PartId            uint `gorm:"primaryKey"`
	PartDiagramNumber int
	PartNumber        string
	PartDescription   string
}

func main() {
	db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}
	db.AutoMigrate(&Diagram{}, &Part{}, &DiagramPart{})
	diagram := &Diagram{}
	err = db.Debug().Where("id = ?", 1).
		// Select("diagrams.*, diagram_parts.part_number, diagram_parts.part_description").
		Preload("Parts", func(db *gorm.DB) *gorm.DB {
			return db.Select("parts.*, diagram_parts.part_number, diagram_parts.part_description").
				Joins("left join diagram_parts on diagram_parts.part_id = parts.id")
		}).
		// Joins("left join diagram_parts on diagram_parts.diagram_id = diagrams.id").
		First(diagram).Error
	if err != nil {
		panic(err)
	}

	fmt.Printf("diagram: %v\n", diagram)
	fmt.Println("part number:", diagram.Parts[0].PartNumber)
}

huangapple
  • 本文由 发表于 2022年5月30日 14:15:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/72429858.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定