函数式编程
有一种方法可以在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 Customerdb.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
拉风的咖菲猫
注意:从纯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);您可能还希望所有数据都与“公司”和“客户”列一起,并在前端决定使用哪些数据:RelationSELECT 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);