private async Task InternalLoadDtoArrayAsync <TTargetDto, TKeyProvider>(RelatedDtoProperty.RelatedDtoProperty relatedProperty, RelatedValueType idType, IDtoLoadRule loaderRule, TTargetDto[] arrTargetDtos, TKeyProvider[] arrKeyProviders) where TTargetDto : class where TKeyProvider : class { var dtoType = relatedProperty.DtoType; var keyProviderWithIds = arrKeyProviders.ToDictionary(x => x, keyProvider => ((IEnumerable)idType.Property.GetValue(keyProvider)).Cast <object>().ToArray()); var idsToLoad = keyProviderWithIds.Values.Where(x => x != null).SelectMany(x => x).Where(x => x != null) .Distinct().ToArray(); Dictionary <object, object> dictLoadedDtos = null; var dtoElementType = dtoType.ElementType; if (idsToLoad.Any()) { var relatedDtos = (await loaderRule.LoadAsObjectAsync(_serviceProvider, idsToLoad)).ToArray(); dictLoadedDtos = relatedDtos.ToDictionary(loaderRule.GetKey, x => x); } for (var index = 0; index < arrTargetDtos.Length; index++) { var targetDto = arrTargetDtos[index]; var keyProvider = arrKeyProviders[index]; object propValue = null; var desiredDtoKeys = keyProviderWithIds[keyProvider]; if (desiredDtoKeys != null) { var dtoArray = Array.CreateInstance(dtoType.ElementType, desiredDtoKeys.Length); for (var i = 0; i < desiredDtoKeys.Length; i++) { var desiredDtoKey = desiredDtoKeys[i]; object dto = null; if (desiredDtoKey != null && dictLoadedDtos.ContainsKey(desiredDtoKey)) { dto = dictLoadedDtos[desiredDtoKey]; } dtoArray.SetValue(dto, i); } propValue = dtoArray; } dtoType.Property.SetValue(targetDto, propValue); } }
private async Task InternalLoadDtoAsync <TTargetDto, TKeyProvider>(RelatedDtoProperty.RelatedDtoProperty relatedProperty, RelatedValueType idType, IDtoLoadRule loaderRule, TTargetDto[] arrTargetDtos, TKeyProvider[] arrKeyProviders) where TTargetDto : class where TKeyProvider : class { var dtoType = relatedProperty.DtoType; var keyProviderWithIds = arrKeyProviders.ToDictionary(x => x, keyProvider => idType.Property.GetValue(keyProvider)); var idsToLoad = keyProviderWithIds.Values.Where(x => x != null).Distinct().ToArray(); Dictionary <object, object> dictLoadedDtos = null; if (idsToLoad.Any()) { var relatedDtos = (await loaderRule.LoadAsObjectAsync(_serviceProvider, idsToLoad)).ToArray(); dictLoadedDtos = relatedDtos.ToDictionary(x => loaderRule.GetKey(x), x => x); } for (var index = 0; index < arrTargetDtos.Length; index++) { var targetDto = arrTargetDtos[index]; var keyProvider = arrKeyProviders[index]; object propValue = null; var desiredDtoKey = keyProviderWithIds[keyProvider]; if (desiredDtoKey != null && dictLoadedDtos.ContainsKey(desiredDtoKey)) { propValue = dictLoadedDtos[desiredDtoKey]; } dtoType.Property.SetValue(targetDto, propValue); } }
public async Task <IEnumerable <TTargetDto> > LoadListAsync <TTargetDto, TKeyProvider>( IEnumerable <TTargetDto> targetDtos, IEnumerable <TKeyProvider> keyProviders) where TTargetDto : class where TKeyProvider : class { var targetDtoType = typeof(TTargetDto); var relatedDtoProperties = _configuration.GetRelatedDtoProperties(targetDtoType); if (relatedDtoProperties == null) { throw new UnsupportedTargetTypeException(targetDtoType); } var keyProviderType = typeof(TKeyProvider); var isKeyProviderSameType = targetDtoType == keyProviderType; var arrTargetDtos = targetDtos.ToArray(); var arrKeyProviders = keyProviders.ToArray(); foreach (var relatedProperty in relatedDtoProperties) { var dtoType = relatedProperty.DtoType; var dtoProperty = dtoType.Property; var attribute = relatedProperty.Attribute; RelatedValueType idType = null; if (isKeyProviderSameType) { idType = relatedProperty.IdType; } else { if (dtoType.GenericType != null || dtoType.IsArray) { throw new MissingIdPropertyNameException(targetDtoType.Name, dtoProperty.Name); } var idProp = keyProviderType.GetProperty(attribute.IdPropertyName ?? dtoProperty.Name + "Id", BindingFlags.Public | BindingFlags.Instance); if (idProp != null) { idType = new RelatedValueType(idProp); } } if (idType == null) { continue; } var loaderRule = _configuration.GetLoadRule(dtoType.ElementType); if (loaderRule == null) { continue; } if (dtoType.GenericType != null) { await InternalLoadDtoEnumerableAsync(relatedProperty, idType, loaderRule, arrTargetDtos, arrKeyProviders); } else if (dtoType.IsArray) { await InternalLoadDtoArrayAsync(relatedProperty, idType, loaderRule, arrTargetDtos, arrKeyProviders); } else { await InternalLoadDtoAsync(relatedProperty, idType, loaderRule, arrTargetDtos, arrKeyProviders); } } return(arrTargetDtos); }