覆盖 gorm 中的外键和引用

Override both foreign key and references in gorm

我定义了两个数据库结构

type Main struct {
    gorm.Model
    GroupID   int64  `gorm:"column:group_id"`
    GroupName string `gorm:"column:group_name"`
    ItemID    string `gorm:"column:item_id"`
    Item      Item   `gorm:"foreignKey:ItemID;references:item_id"`
}

type Item struct {
    gorm.Model
    ItemID   string `gorm:"column:item_id"`
    ItemName string `gorm:"column"item_name"`
}

但是,当我执行 select 时,即

mains := make([]*Main, 0)
db.Where(someFilters).Preload("Item").Find(&mains)

我收到了查询

SELECT * FROM mains WHERE condition1='condition_value';
SELECT * FROM items WHERE item_id IN (1, 2); # Uses Main's ID field as the argument instead

IN 查询使用 Main 结构的主键 id 而不是使用字段 item_id。我在这里做错了什么吗?我只想通过 item_id 获得“加入”结果,即我希望第二个查询是

SELECT * FROM items WHERE item_id IN (`main_1_item_id`, `main_2_item_id`);

更新:还尝试将标签更改为 association_foreign_key

type Main struct {
    gorm.Model
    GroupID   int64  `gorm:"column:group_id"`
    GroupName string `gorm:"column:group_name"`
    ItemID    string `gorm:"column:item_id"`
    Item      Item   `gorm:"association_foreignkey:ItemID;references:item_id"`
}

现在生成的SQL是

SELECT * FROM mains WHERE condition1='condition_value';
SELECT * FROM items WHERE id IN (`main_1_item_id`, `main_2_item_id`); # Uses Main's ItemID field but using Item's ID field as query

参考文献:

[1] https://gorm.io/docs/belongs_to.html

我有一些您可能想要研究的想法:

首先:既然你的 Main 结构中有一个 Item 结构,你为什么要为 ItemID 使用第二个字段,你已经在 Item 结构中有一个。 Gorm 非常擅长自动处理关联,尝试简单地将 Item 结构嵌入到 Main 结构中。

其次:当你嵌入gorm.Model时,它将其Id字段声明为结构的主键,这也可能导致问题。

我找到了解决问题的方法。

gorm 标签应该是

type Main struct {
    gorm.Model
    GroupID   int64  `gorm:"column:group_id"`
    GroupName string `gorm:"column:group_name"`
    ItemID    string `gorm:"column:item_id"`
    Item      Item   `gorm:"associationForeignKey:ItemID;foreignKey:ItemID"`
}

type Item struct {
    gorm.Model
    ItemID   string `gorm:"column:item_id"`
    ItemName string `gorm:"column"item_name"`
}

现在生成的 SQL 查询是

SELECT * FROM mains WHERE condition1='condition_value';
SELECT * FROM items WHERE item_id IN (`main_1_item_id`, `main_2_item_id`);