Improved preload m2m performance

This commit is contained in:
Dirk-Jan 2016-05-09 14:15:35 +02:00
parent bf413d67d3
commit d02c2a37ea
1 changed files with 14 additions and 6 deletions

View File

@ -153,16 +153,24 @@ func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{})
) )
if indirectScopeValue.Kind() == reflect.Slice { if indirectScopeValue.Kind() == reflect.Slice {
preloadMap := make(map[string][]reflect.Value)
for i := 0; i < resultsValue.Len(); i++ { for i := 0; i < resultsValue.Len(); i++ {
result := resultsValue.Index(i) result := resultsValue.Index(i)
foreignValues := getValueFromFields(result, relation.ForeignFieldNames) foreignValues := getValueFromFields(result, relation.ForeignFieldNames)
for j := 0; j < indirectScopeValue.Len(); j++ { preloadMap[toString(foreignValues)] = append(preloadMap[toString(foreignValues)], result)
object := indirect(indirectScopeValue.Index(j))
if equalAsString(getValueFromFields(object, relation.AssociationForeignFieldNames), foreignValues) {
objectField := object.FieldByName(field.Name)
objectField.Set(reflect.Append(objectField, result))
break
} }
objects := scope.IndirectValue()
for j := 0; j < objects.Len(); j++ {
object := reflect.Indirect(objects.Index(j))
objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames)
objectStringValue := toString(objectRealValue)
if results, ok := preloadMap[objectStringValue]; ok {
if object.Kind() == reflect.Ptr {
object = object.Elem()
}
f := object.FieldByName(field.Name)
f.Set(reflect.Append(f, results...))
} }
} }
} else { } else {