为了账号安全,请及时绑定邮箱和手机立即绑定

我应该如何引用两个具有单个外键的表?

我应该如何引用两个具有单个外键的表?

Go
摇曳的蔷薇 2022-08-01 09:35:26
我有一个公司模型,我有一个客户模型。两者都可以是一种关系。type Customer struct {    gorm.Model    Title string}type Company struct {    gorm.Model    Title string}type Relation struct {    gorm.Model    CustomerOrCompanyID uint}所以两者都是一种关系。我怎样才能让我的关系指向公司或客户?
查看完整描述

2 回答

?
函数式编程

TA贡献1807条经验 获得超9个赞

有一种方法可以在Gorm中使用多态的Haive One关系自然地做到这一点。这将使您能够轻松运行@TheSphinX提供的一些查询。


但是,您需要向关系表添加类型鉴别器列才能使其正常工作:


type Customer struct {

    gorm.Model

    Title string

    Rel   Relation `gorm:"polymorphic:Owner"`

}


type Company struct {

    gorm.Model

    Title string

    Rel   Relation `gorm:"polymorphic:Owner"`

}


type Relation struct {

    gorm.Model

    Foo       string

    OwnerID   uint

    OwnerType string

}

现在,您可以正常创建记录:


cust := Customer{

    Title: "Cust",

    Rel:   Relation{Foo: "bar"},

}

comp := Company{

    Title: "Comp",

    Rel:   Relation{Foo: "baz"},

}

db.Create(&cust)

db.Create(&comp)

若要运行一个查询,获取客户或公司以及@TehSphinX前两个查询中的相关信息,请执行如下操作:


var cust Customer

db.Joins("Rel").First(&cust, 1)

最后一个查询会更复杂,但也可以使用自定义行结构和联接来完成:


var rows []struct {

    Relation

    Customer Customer `gorm:"embedded;embeddedPrefix:cust_"`

    Company  Company  `gorm:"embedded;embeddedPrefix:comp_"`

}


db.Select(`

        relations.*,

        customers.id AS cust_id,

        customers.title AS cust_title,

        companies.id AS comp_id,

        companies.title AS comp_title

    `).

    Model(&Relation{}).

    Joins("LEFT JOIN customers ON relations.owner_id = customers.id AND relations.owner_type = 'customers'").

    Joins("LEFT JOIN companies ON relations.owner_id = companies.id AND relations.owner_type = 'companies'").

    Find(&rows)


// now rows[i].Relation is filled, and rows[i].Customer or rows[i].Company 

// are non-zero depending on rows[i].Relation.OwnerType


查看完整回答
反对 回复 2022-08-01
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

注意:从纯SQL的角度来说,因为我还没有使用过:gorm


在我上面的评论中,我问:


您如何知道 中的 ID 是客户 ID 还是公司 ID?您是否有一些布尔字段说这是不是客户?还是 ID 本身包含该信息?喜欢和?CustomerOrCompanyIDcust-1234comp-1234


由于您需要一种方法来区分哪种ID,因此我建议使用两个字段:和。其中之一始终是(或)。CustomerOrCompanyIDCustomerIDCompanyID0NULL


这样,您就可以知道要联接哪个表,也可以同时联接两者,具体取决于每行具有的数据类型,将填充客户或公司的列。


我认为如果有2个字段,应该不会再有问题了,因为它会将它们中的每一个都处理为一个正常的关系,而不是为所有列设置。gorm


一些示例 SQL 语句 (MySQL Dialekt):


所有客户:


SELECT 

    Relation.ID as RelID, Relation.OtherColumn,

    Customer.ID, Customer.Name

    /* etc. */

FROM 

    Relation INNER JOIN Customer ON (Relation.CustomerID=Customer.ID);

所有公司:


SELECT 

    Relation.ID as RelID, Relation.OtherColumn, 

    Company.ID, Company.Name

    /* etc. */

FROM 

    Relation INNER JOIN Company ON (Relation.CompanyID=Company.ID);

您可能还希望所有数据都与“公司”和“客户”列一起,并在前端决定使用哪些数据:Relation


SELECT 

    Relation.ID as RelID, 

    Relation.OtherColumn, 

    Customer.ID as CustID,

    Customer.Name as CustName,

    Company.ID as CompID,

    Company.Name as CompName,

    /* etc. */

FROM 

    Relation 

    LEFT JOIN Company ON (Relation.CompanyID=Company.ID)

    LEFT JOIN Customer ON (Relation.CustomerID=Customer.ID);


查看完整回答
反对 回复 2022-08-01
  • 2 回答
  • 0 关注
  • 125 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号