如何删除关联(多对多)?

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

How to delete association (many2many)?

问题

奇怪的行为发生在删除关联时。
查询生成了一个额外的条件,我没有添加。

  1. type Client struct {
  2. gorm.Model
  3. Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
  4. Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
  5. Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
  6. Operators []*Operator `gorm:"many2many:client_operators;"`
  7. Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // 占位字段,不会成为表的一部分
  8. }
  9. type Operator struct {
  10. gorm.Model
  11. Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
  12. Email string `gorm:"not null" validate:"required,email"`
  13. Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
  14. Last_online time.Time `gorm:"default:null" validate:"omitempty"`
  15. Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
  16. Clients []*Client `gorm:"many2many:client_operators;"`
  17. Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
  18. }
  19. // 查找与客户相关的运营商
  20. var client_query *Client
  21. DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
  22. // 删除与客户相关的运营商
  23. DBconnection.Model(&Client{}).Where("client_id = ?", pk).Association("Operators").Delete(&client_query.Operators)

我期望的删除操作是:

[2.000ms] [rows:0] DELETE FROM client_operators WHERE client_id = 5 AND client_operators.operator_id = 1

或者

[2.000ms] [rows:0] DELETE FROM client_operators WHERE client_operators.client_id = 5 AND client_operators.operator_id = 1

但实际上它执行的是:

[2.000ms] [rows:0] DELETE FROM client_operators WHERE client_id = 5 AND client_operators.client_id IN (NULL) AND client_operators.operator_id = 1

它添加了额外的条件 " AND client_operators.client_id IN (NULL) "。

我尝试了 Association().Clear(),但也没有起作用。

英文:

Strange behaviour deleting association happened.
The query generated an extra condition which i did not add.

  1. type Client struct {
  2. gorm.Model
  3. Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
  4. Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
  5. Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
  6. Operators []*Operator `gorm:"many2many:client_operators;"`
  7. Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // placeholder field, wont be part of table
  8. }
  9. type Operator struct {
  10. gorm.Model
  11. Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
  12. Email string `gorm:"not null" validate:"required,email"`
  13. Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
  14. Last_online time.Time `gorm:"default:null" validate:"omitempty"`
  15. Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
  16. Clients []*Client `gorm:"many2many:client_operators;"`
  17. Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
  18. }
  19. // find operators related to client
  20. var client_query *Client
  21. DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
  22. // delete operators related to client
  23. DBconnection.Model(&Client{}).Where("client_id = ?", pk).Association("Operators").Delete(&client_query.Operators)

I expect the deletion to be:

[2.000ms] [rows:0] DELETE FROM `client_operators` WHERE client_id = 5 AND `client_operators`.`operator_id` = 1

OR

[2.000ms] [rows:0] DELETE FROM `client_operators` WHERE `client_operators`.`client_id` = 5 AND `client_operators`.`operator_id` = 1

However it currently does:

[2.000ms] [rows:0] DELETE FROM `client_operators` WHERE client_id = 5 AND `client_operators`.`client_id` IN (NULL) AND `client_operators`.`operator_id` = 1

It adds the extra condition of " AND `client_operators`.`client_id` IN (NULL) "

I tried Association().Clear() and did not do anything too.

答案1

得分: 1

这是因为你将&Client{}传递给了Model

根据gorm文档,你需要首先构建一个具有有效Id的客户端,像这样:

  1. type Client struct {
  2. gorm.Model
  3. Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
  4. Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
  5. Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
  6. Operators []*Operator `gorm:"many2many:client_operators;"`
  7. Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // 占位字段,不会成为表的一部分
  8. }
  9. type Operator struct {
  10. gorm.Model
  11. Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
  12. Email string `gorm:"not null" validate:"required,email"`
  13. Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
  14. Last_online time.Time `gorm:"default:null" validate:"omitempty"`
  15. Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
  16. Clients []*Client `gorm:"many2many:client_operators;"`
  17. Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
  18. }
  19. // 查找与客户端相关的运营商
  20. var client_query *Client
  21. DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
  22. // 删除与客户端相关的运营商
  23. DBconnection.Model(&Client{ID: pk}).Association("Operators").Delete(&client_query.Operators)
英文:

This is happening because you're passing &Client{} to Model.

Looking at gorm docs you need to construct a client with a valid Id first like this:

  1. type Client struct {
  2. gorm.Model
  3. Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
  4. Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
  5. Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
  6. Operators []*Operator `gorm:"many2many:client_operators;"`
  7. Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // placeholder field, wont be part of table
  8. }
  9. type Operator struct {
  10. gorm.Model
  11. Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
  12. Email string `gorm:"not null" validate:"required,email"`
  13. Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
  14. Last_online time.Time `gorm:"default:null" validate:"omitempty"`
  15. Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
  16. Clients []*Client `gorm:"many2many:client_operators;"`
  17. Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
  18. }
  19. // find operators related to client
  20. var client_query *Client
  21. DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
  22. // delete operators related to client
  23. DBconnection.Model(&Client{ID: pk}).Association("Operators").Delete(&client_query.Operators)

huangapple
  • 本文由 发表于 2022年3月22日 18:21:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/71570355.html
匿名

发表评论

匿名网友

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

确定