xormのオートインクリメントタグをsliceで利用した時に、痒いところに手が届かない話
xormのオートインクリメントタグをsliceで利用した時に、痒いところに手が届かない話
この記事はGo2 Advent Calendar 2019に参加しています。
まとめ
xormのオートインクリメントタグをsliceで利用する時、
インサート後にオートインクリメント値を再利用する場合は、
同じsliceを回すループ内でアクセスしないと初期化されて取得できない。
スライスではなく単体で構造体を宣言している場合は、初期化されずそのまま再利用可能です。
構造体を定義
type SampleOutsideInput struct {
Items []*SampleOutsideItemInput `json:"items"` // slice型を定義
}
type SampleOutsideItemInput struct {
ID uint64 `xorm:"pk autoincr" json:"-"` // こいつ
Number uint64 `json:"repairNumber""`
}
先にインサートしてオートインクリメントIDを再利用しようと取得すると取れない
インサートしてみる
func (u *SampleOutside) Create(params *model.SampleOutsideInput) (bool error) {
session := u.engine.NewSession()
defer session.Close()
// 楽してsliceをインサートしよう
_, err = session.Table("t_sample_items").Insert(¶ms.Items)
if err != nil {
return err
}
オートインクリメント指定したIDをKeyに再利用して別テーブルにインサートしようとするとエラー
for _, v := range params.Items {
_, err = session.Table("t_sample_histories").
Insert(&model.EquipmentHistoriesInput{
TransactionID: v.ID, // こいつが取得できずにエラー
TransactionNumber: v.SampleNumber,
TransactionDetailNumber: v.SampleDetailNumber,
})
if err != nil {
return err
}
}
どうすれば取れるか
同じsliceを回すループの中でアクセスすれば取得できる
session := u.engine.NewSession()
defer session.Close()
for _, v := range params.Items {
// ループ外でインサートしてたのをループ内に移動
_, err := session.Table("t_sample_items").Insert(v)
if err != nil {
return err
}
// 同じループ内でアクセスすると
_, err = session.Table("t_sample_histories").
Insert(&model.EquipmentHistoriesInput{
TransactionID: v.ID, // 取得できる
TransactionNumber: v.SampleNumber,
TransactionDetailNumber: v.SampleDetailNumber,
})
if err != nil {
return err
}
}
}