How to Eager Loading belongs to relationship using GORM

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

How to Eager Loading belongs to relationship using GORM

问题

我有这两个结构体:

// User 属于 CompanyCompanyID 是外键
type User struct {
gorm.Model
Name string
CompanyID int
Company Company
}

type Company struct {
ID int
Name string
}

如果我想查询包含 Company 数据的 User,可以这样做:

user := new(User)
db.Preload("Company").Find(user)

但是我想查询包含 User 数据的 Company,如果我这样做:

company := new(Company)
db.Preload("User").Find(company)

会抛出一个错误:

"User: unsupported relations for schema Company"

这是可以理解的,因为 Company 结构体中没有 User 字段。

如果我像这样添加 User 字段:

type Company struct {
ID int
Name string
User User
}

会抛出错误:

"illegal cycle in declaration of User"

英文:

I have these two structs:

// `User` belongs to `Company`, `CompanyID` is the foreign key
type User struct {
  gorm.Model
  Name      string
  CompanyID int
  Company   Company
}

type Company struct {
  ID   int
  Name string
}

If I want to query User with Company data included in it, I can do this:

user := new(User)
db.Preload("Company").Find(user)

But I want to query Company and include User in it, If I do this

company := new(Company)
db.Preload("User").Find(company)

It will throw an error like:

> "User: unsupported relations for schema Company"

That's understandable, because there is no field User in Company struct.

if I add User field like this:

type Company struct {
      ID   int
      Name string
      User User
}

it throws error like:

> "illegal cycle in declaration of User"

答案1

得分: 1

根据@kaushik在评论中的建议,一个可行的解决方案可能是:

package main

import (
	"fmt"

	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type User struct {
	gorm.Model
	Name      string
	CompanyID int
	Company   Company
}

type Company struct {
	ID   int
	Name string
	User *User
}

func main() {
	dsn := "host=localhost port=54322 user=postgres password=postgres dbname=postgres sslmode=disable"
	db, err := gorm.Open(postgres.Open(dsn))
	if err != nil {
		panic(err)
	}

	db.AutoMigrate(&Company{})
	db.AutoMigrate(&User{})
	// db.Create(&Company{ID: 1, Name: "ACME", User: &User{Name: "John"}})
	// db.Create(&User{Model: gorm.Model{ID: 2}, Name: "Suzy", Company: Company{ID: 2, Name: "XYZ"}})
	var company Company
	if err := db.Debug().Model(&Company{}).Preload("User").Find(&company).Error; err != nil {
		panic(err)
	}
	fmt.Println("User:", company.User.Name)
}

如果有帮助,请告诉我,谢谢!

英文:

As suggested in the comments by @kaushik, a working solution could be:

package main

import (
	"fmt"

	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type User struct {
	gorm.Model
	Name      string
	CompanyID int
	Company   Company
}

type Company struct {
	ID   int
	Name string
	User *User
}

func main() {
	dsn := "host=localhost port=54322 user=postgres password=postgres dbname=postgres sslmode=disable"
	db, err := gorm.Open(postgres.Open(dsn))
	if err != nil {
		panic(err)
	}

	db.AutoMigrate(&Company{})
	db.AutoMigrate(&User{})
	// db.Create(&Company{ID: 1, Name: "ACME", User: &User{Name: "John"}})
	// db.Create(&User{Model: gorm.Model{ID: 2}, Name: "Suzy", Company: Company{ID: 2, Name: "XYZ"}})
	var company Company
	if err := db.Debug().Model(&Company{}).Preload("User").Find(&company).Error; err != nil {
		panic(err)
	}
	fmt.Println("User:", company.User.Name)
}

Let me know if this helps you, thanks!

huangapple
  • 本文由 发表于 2023年6月7日 11:35:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76419750.html
匿名

发表评论

匿名网友

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

确定