GORM多对多自定义连接表查询如何获取包含已软删除的关联数据
问题原因
你自定义的连接表VehicleUser嵌入了gorm.Model,自带软删除字段DeletedAt,GORM 默认查询连接表时会自动追加deleted_at IS NULL的过滤条件。你原来的写法仅为主表User和关联表Vehicle加了Unscoped配置,没有覆盖连接表的查询逻辑,因此会出现你遇到的问题。
解决方案
GORM 1.21+ 版本提供了JoinTableUnscoped会话配置,专门用于控制多对多关联的连接表是否忽略软删除,正确的查询写法如下:
var users []User // 注意要获取所有用户需用切片类型,而非单个User实例 err := db.Unscoped(). Preload("Vehicles", func(tx *gorm.DB) *gorm.DB { // 同时配置关联表Vehicle忽略软删除,以及连接表vehicle_users忽略软删除 return tx.Unscoped().Session(&gorm.Session{JoinTableUnscoped: true}) }). Find(&users).Error if err != nil { // 自定义错误处理逻辑 }
执行上述代码后,GORM 生成的连接表查询语句会自动去掉vehicle_users.deleted_at IS NULL条件,同时查询已删除和未删除的关联关系。
高性能备选方案
如果你需要更高的查询性能,也可以自定义JOIN逻辑一次性拉取所有数据,避免多次查询:
type UserWithVehicle struct { User Vehicle `gorm:"embedded"` } var res []UserWithVehicle err := db.Unscoped().Model(&User{}). Select("users.*, v.*"). Joins("LEFT JOIN vehicle_users vu ON vu.user_id = users.id"). Joins("LEFT JOIN vehicles v ON v.id = vu.vehicle_id"). Scan(&res).Error
这种写法只会生成一条SQL语句,适合数据量较大的场景。
内容的提问来源于stack exchange,提问作者igor001
相关产品推荐
相关产品推荐

