基于多个条件建立Gorm的一对一关系

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

Gorm one to one relationship based on multiple conditions

问题

我正在尝试在GORM中实现一个不仅仅基于id外键的关系。数据库结构的快速概述如下:

有一个order表,其中包含一个tableNo列,通常是一个整数,但也可以是一个字符串(有些表格是B2)。需要将表号与table表中的一个表格(行)匹配起来(对于混淆的数据库表名表示抱歉)。这个关系是通过venueIdtableNo来完成的。

如果我要在MySQL中编写这个关系,我们可以使用以下语句连接这些表格:

select o.tableNo, o.venueId, t.title, t.venueId from `order` o
left join `table` t on t.venueId = o.venueId
where replace(t.title, "Table #", '') = o.tableNo 
order by o.createdAt desc;
tableNo (order) venueId (order) title (table) venueId (table)
7 2229 Table #7 2229
9 2462 Table #9 2462
15 2229 Table #15 2229

在我的模型中,我写了以下代码:

type Order struct {
	Id      int    `json:"id,omitempty"`
	VenueId int    `gorm:"column:venueId" json:"venueId,omitempty"`
	TableNo string `gorm:"column:tableNo" json:"tableNo,omitempty"`
	Table   Table  `gorm:"references:Title,foreignKey:TableNo" json:"table"`
}
type Table struct {
	Id      int    `gorm:"column:id" json:"id,omitempty"`
	VenueId int    `gorm:"column:venueId" json:"venueId,omitempty"`
	Title   string `gorm:"column:title" json:"title,omitempty"`
}

显然,有一些缺少的地方,比如在表模型中对tableNo进行替换。我还需要使用venueId将table对象连接到order上。即使我指定的关系不完整,Gorm目前仍会给出错误need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface

我的当前解决方案只是手动执行查询,因为这正是GORM在使用preload时会做的。(即order.Table = query_result

如果您对如何以清晰的方式表达这种关系有任何建议,我将非常感激。

谢谢!

英文:

I am trying to implement a relationship in GORM that isn't simply based on id foreign key. A quick overview of database structure:

There is an order table which contains a tableNo column which is generally an integer but can also be a string (some tables are say B2). The table number needs to be matched up to a table (row) in the table table (sorry for confusing database table names). This relationship is done through venueId and tableNo.

If I was to write this relationship in MySQL we could join the tables using the following:

select o.tableNo, o.venueId, t.title, t.venueId from order o
left join table t on t.venueId = o.venueId
where replace(t.title, "Table #", '') = o.tableNo
order by o.createdAt desc;

tableNo (order) venueId (order) title (table) venueId (table)
7 2229 Table #7 2229
9 2462 Table #9 2462
15 2229 Table #15 2229

In my model I have written the following:

type Order struct {
	Id      int    `json:"id,omitempty"`
	VenueId int    `gorm:"column:venueId" json:"venueId,omitempty"`
	TableNo string `gorm:"column:tableNo" json:"tableNo,omitempty"`
	Table   Table  `gorm:"references:Title,foreignKey:TableNo" json:"table"`
}
type Table struct {
	Id      int    `gorm:"column:id" json:"id,omitempty"`
	VenueId int    `gorm:"column:venueId" json:"venueId,omitempty"`
	Title   string `gorm:"column:title" json:"title,omitempty"`
}

Clearly there are certain things missing, i.e replace on the tableNo in the table model. I also need to connect the table object to the order using the venueId. Gorm currently gives an error need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface anyway even though the relationship I specified isn't complete.

My current solution is just to manually execute the query as this is what GORM would do anyway with a preload. (i.e order.Table = query_result)

If you have any suggestions as to how to express this relationship in a clean way I would be very grateful.

Thanks

答案1

得分: 1

我已经找到了一个解决方案。

第一个主要问题是语法错误,导致GORM没有给我任何查询日志。gorm:"references:Title,foreignKey:TableNo" json:"table" 应该改为 gorm:"references:Title;foreignKey:TableNo" json:"table"

接下来,我将关系更改为venueId,因为回想起SQL,这就是连接操作所基于的内容,所以我们有 gorm:"foreignKey:VenueId;references:VenueId" json:"table"

最后,preload必须包含一个条件来匹配表号的值:

r.db.Preload("Table", "replace(`table`.title, 'Table #', '') = ?", &order.TableNo).First(&order, id)

现在的问题是如何不使用replace,并以一种方式进行操作,使得除了 'Table #' 之外的字符串也可以出现在tableNo之前。

希望有人会发现这个有用!

英文:

I have managed to figure out a solution.

The first main problem was a syntax error which stopped GORM from giving me any query logs. gorm:"references:Title,foreignKey:TableNo" json:"table" should have been gorm:"references:Title;foreignKey:TableNo" json:"table"

Next I changed the relationship to venueId as thinking back to the SQL this is what the join operation was being made on so we have gorm:"foreignKey:VenueId;references:VenueId" json:"table"

Finally the preload had to have a condition included to match the table number value:

r.db.Preload("Table", "replace(`table`.title, 'Table #', '') = ?", &order.TableNo).First(&order, id)

Now the question is how to not use replace and do this in a way where strings apart from 'Table #' can be in front of tableNo.

Hope someone finds this useful!

huangapple
  • 本文由 发表于 2021年9月3日 20:51:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/69045274.html
匿名

发表评论

匿名网友

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

确定