我试图建立多对多的关系,所以我有3个结构:
type Orders struct {
ID int64
CustomerID string
etc
}
type Products struct {
ID int64
Name string
Description string
etc
}
type OrderDetails struct {
OrderID int64
ProductID string
Quantity int
}
我认为这是正确的方法,但我现在的问题是我不知道如何将数据存储区密钥放在struct ID中,而不会产生两个client.Put请求,因为据我所知,{ {1}}在您输入之前不会返回新的键值..
我想有些人会建议使用datastore.IncompleteKey("Products", nil)
代替key *datastore.Key
,但我更愿意将密钥转换为ID
非常感谢任何帮助
答案 0 :(得分:2)
一个选项是提前分配密钥,您可以在调用Client.Put()
之前在结构中设置密钥。
您可以使用Client.AllocateIDs()
分配ID。您可以将一片不完整的密钥传递给它,然后您将获得一小部分完整的datastore.Key
s,数据存储区为您保留(并因此保证不会向其他人提供"保存具有不完整键的实体时使用)。您可以在Key.ID
字段中访问已分配密钥的数字ID。
但是在实体中存储数字密钥ID是多余的,我发现这是浪费(资源)。每当你加载一个实体时,例如使用Client.Get()
或多个Client.GetAll()
,您也可以取回密钥,并且可以在结构中填写数字ID"手动"作为后处理步骤。您还可以将此后处理功能包装在一个函数中,只要您从数据存储区获取实体,就可以为您执行此操作。
例如,如果您加载了OrderDetails
实体,其中包含OrderID
,则可以使用datastore.IDKey()
为相应的{{1}构建datastore.Key
} 实体。这样做的例子:
Order
这意味着你不应该存储"自我ID"在实体中,如果数字ID已知,则可以构造var orderDetails OrderDetails
// Load orderDetails
orderKey := datastore.IDKey("order", orderDetails.OrderID, nil)
// Now you have the key for the Order entity
var order Order
err := client.Get(ctx, orderKey, &order)
值。