如何使用可为空的ForeignKey进行预加载

问题描述 投票:1回答:1

我有以下示例:

type PostModel struct {
    Id             int64     `gorm:"primary_key;AUTO_INCREMENT;column:id"`
    UserId         *int64    `gorm:"column:userId;"`
    User         UserModel         `gorm:"ForeignKey:Id;AssociationForeignKey:UserId"`
}
type UserModel struct {
    Id        int64     `gorm:"primary_key;AUTO_INCREMENT;column:id"`
}

使用时

db.Model(&model.PostModel{}).Where(where).Preload("User").Find(&post)

我得到了正确的答复,但是出了点问题。

SELECT * FROM `user`  WHERE (`id` IN (?,?,?,?,?,?,?,?,?,?))[0xc00023dce0 0xc00023dda0 0xc00023d9e0 0xc00023d920 0xc00023daa0 0xc00023db60 0xc00023dc20 0xc00023de60 0xc00023df20 0xc00023d790] 1

所有用户ID为1,但在gorm sql中,它使用指针地址替换数字。像0xc00023dce0 0xc00023dda0 0xc00023d9e0 0xc00023d920 0xc00023daa0 0xc00023db60 0xc00023dc20 0xc00023de60 0xc00023df20 0xc00023d790如何解决?

go preload go-gorm
1个回答
0
投票

我按照您的描述编写了示例代码,并将Gorm置于日志模式以查看SQL,但它会打印正确的SQL:

[2020-03-29 21:29:42]  [0.17ms]  SELECT * FROM "post_models"
[4 rows affected or returned ]

[2020-03-29 21:29:42]  [0.18ms]  SELECT * FROM "user_models"  WHERE ("id" IN (1,2,1,3))
[3 rows affected or returned ]

如您所见,查询是正确的。

package main

import (
    "fmt"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "log"
    "os"
)

type PostModel struct {
    Id     int64     `gorm:"primary_key;column:id"`
    UserId *int64    `gorm:"column:userId;"`
    User   UserModel `gorm:"ForeignKey:UserId"`
}

type UserModel struct {
    Id int64 `gorm:"primary_key;column:id"`
}

func preloadingSample() error {
    _ = os.Remove("test.db") // Remove file to make sure DB is empty
    db, err := gorm.Open("sqlite3", "test.db")
    if err != nil {
        return fmt.Errorf("open DB failed: %w", err)
    }
    defer db.Close()
    db.LogMode(true)


    err = db.AutoMigrate(
        &PostModel{},
        &UserModel{},
    ).Error
    if err != nil {
        return fmt.Errorf("migration failed: %w", err)
    }

    // Put some sample data in DB
    sampleUsers := []UserModel{
        {},
        {},
        {},
    }
    for idx := range sampleUsers {
        err = db.Create(&sampleUsers[idx]).Error
        if err != nil {
            return fmt.Errorf("failed to create: %w", err)
        }
    }

    samplePosts := []PostModel{
        {User: sampleUsers[0]},
        {User: sampleUsers[1]},
        {User: sampleUsers[0]},
        {User: sampleUsers[2]},
    }
    for idx := range samplePosts {
        err = db.Create(&samplePosts[idx]).Error
        if err != nil {
            return fmt.Errorf("failed to create: %w", err)
        }
    }

    var posts []PostModel
    err = db.Preload("User").Find(&posts).Error
    if err != nil {
        return fmt.Errorf("error in find: %w", err)
    }
    fmt.Printf("%+v\n", posts)
    return nil
}

func main() {
    err := preloadingSample()
    if err != nil {
        log.Fatal(err)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.