fix: duplicated preload

This commit is contained in:
yetone 2024-04-09 00:06:19 +08:00
parent 1e13fd7543
commit f47c2578fa
No known key found for this signature in database
GPG Key ID: 222BA52B342D52AA
2 changed files with 9 additions and 5 deletions

View File

@ -87,7 +87,7 @@ func embeddedValues(embeddedRelations *schema.Relationships) []string {
// If the current relationship is embedded or joined, current query will be ignored. // If the current relationship is embedded or joined, current query will be ignored.
// //
//nolint:cyclop //nolint:cyclop
func preloadEntryPoint(db *gorm.DB, joins []string, relationships *schema.Relationships, preloads map[string][]interface{}, associationsConds []interface{}) error { func preloadEntryPoint(db *gorm.DB, joins []string, relationships *schema.Relationships, preloads map[string][]interface{}, associationsConds []interface{}, preloaded map[string]struct{}) error {
preloadMap := parsePreloadMap(db.Statement.Schema, preloads) preloadMap := parsePreloadMap(db.Statement.Schema, preloads)
// avoid random traversal of the map // avoid random traversal of the map
@ -116,7 +116,7 @@ func preloadEntryPoint(db *gorm.DB, joins []string, relationships *schema.Relati
for _, name := range preloadNames { for _, name := range preloadNames {
if relations := relationships.EmbeddedRelations[name]; relations != nil { if relations := relationships.EmbeddedRelations[name]; relations != nil {
if err := preloadEntryPoint(db, joins, relations, preloadMap[name], associationsConds); err != nil { if err := preloadEntryPoint(db, joins, relations, preloadMap[name], associationsConds, preloaded); err != nil {
return err return err
} }
} else if rel := relationships.Relations[name]; rel != nil { } else if rel := relationships.Relations[name]; rel != nil {
@ -126,20 +126,24 @@ func preloadEntryPoint(db *gorm.DB, joins []string, relationships *schema.Relati
for i := 0; i < rv.Len(); i++ { for i := 0; i < rv.Len(); i++ {
reflectValue := rel.Field.ReflectValueOf(db.Statement.Context, rv.Index(i)) reflectValue := rel.Field.ReflectValueOf(db.Statement.Context, rv.Index(i))
tx := preloadDB(db, reflectValue, reflectValue.Interface()) tx := preloadDB(db, reflectValue, reflectValue.Interface())
if err := preloadEntryPoint(tx, nestedJoins, &tx.Statement.Schema.Relationships, preloadMap[name], associationsConds); err != nil { if err := preloadEntryPoint(tx, nestedJoins, &tx.Statement.Schema.Relationships, preloadMap[name], associationsConds, preloaded); err != nil {
return err return err
} }
} }
case reflect.Struct: case reflect.Struct:
reflectValue := rel.Field.ReflectValueOf(db.Statement.Context, rv) reflectValue := rel.Field.ReflectValueOf(db.Statement.Context, rv)
tx := preloadDB(db, reflectValue, reflectValue.Interface()) tx := preloadDB(db, reflectValue, reflectValue.Interface())
if err := preloadEntryPoint(tx, nestedJoins, &tx.Statement.Schema.Relationships, preloadMap[name], associationsConds); err != nil { if err := preloadEntryPoint(tx, nestedJoins, &tx.Statement.Schema.Relationships, preloadMap[name], associationsConds, preloaded); err != nil {
return err return err
} }
default: default:
return gorm.ErrInvalidData return gorm.ErrInvalidData
} }
} else { } else {
if _, ok := preloaded[rel.Name]; ok {
continue
}
preloaded[rel.Name] = struct{}{}
tx := db.Table("").Session(&gorm.Session{Context: db.Statement.Context, SkipHooks: db.Statement.SkipHooks}) tx := db.Table("").Session(&gorm.Session{Context: db.Statement.Context, SkipHooks: db.Statement.SkipHooks})
tx.Statement.ReflectValue = db.Statement.ReflectValue tx.Statement.ReflectValue = db.Statement.ReflectValue
tx.Statement.Unscoped = db.Statement.Unscoped tx.Statement.Unscoped = db.Statement.Unscoped

View File

@ -280,7 +280,7 @@ func Preload(db *gorm.DB) {
return return
} }
db.AddError(preloadEntryPoint(tx, joins, &tx.Statement.Schema.Relationships, db.Statement.Preloads, db.Statement.Preloads[clause.Associations])) db.AddError(preloadEntryPoint(tx, joins, &tx.Statement.Schema.Relationships, db.Statement.Preloads, db.Statement.Preloads[clause.Associations], map[string]struct{}{}))
} }
} }