Automapper如何将SettingsDb对象列表扁平化映射为单个FtpSettings对象
实现方案
第一步:实现自定义类型转换器
由于从IList<SettingsDb>到FtpSettings属于非标结构映射,你需要自定义类型转换器实现取值、类型转换逻辑:
using AutoMapper; public class FtpSettingsConverter : ITypeConverter<IList<SettingsDb>, FtpSettings> { public FtpSettings Convert(IList<SettingsDb> source, FtpSettings destination, ResolutionContext context) { // 空集合直接返回默认实例 if (source == null || !source.Any()) return new FtpSettings(); // 转为Name-Value字典简化取值逻辑 var configDict = source.ToDictionary(x => x.Name, x => x.Value); return new FtpSettings { Enabled = bool.TryParse(configDict.GetValueOrDefault(nameof(FtpSettings.Enabled)), out var enabled) ? enabled : false, Server = configDict.GetValueOrDefault(nameof(FtpSettings.Server)), Port = int.TryParse(configDict.GetValueOrDefault(nameof(FtpSettings.Port)), out var port) ? port : 21, Protocol = configDict.GetValueOrDefault(nameof(FtpSettings.Protocol)), SSLStartMode = configDict.GetValueOrDefault(nameof(FtpSettings.SSLStartMode)), User = configDict.GetValueOrDefault(nameof(FtpSettings.User)), Password = configDict.GetValueOrDefault(nameof(FtpSettings.Password)) }; } }
第二步:配置AutoMapper映射规则
在你的AutoMapper Profile配置类中添加映射关系,指定使用上述转换器:
public class MappingProfile : Profile { public MappingProfile() { // 其他映射规则... CreateMap<IList<SettingsDb>, FtpSettings>().ConvertUsing<FtpSettingsConverter>(); } }
第三步:调用映射
拿到过滤后的FTP分组配置列表后,直接调用AutoMapper的映射方法即可:
// 你从数据库查询得到的FTP分组配置列表 IList<SettingsDb> ftpDbSettings = await _dbContext.SettingsDb.Where(x => x.Section == "FTP").ToListAsync(); // 映射得到FtpSettings实例 FtpSettings ftpSettings = _mapper.Map<FtpSettings>(ftpDbSettings);
扩展:通用配置转换器(可选)
如果后续还有其他同结构的配置类(如SmtpSettings、SystemSettings等),可以写泛型通用转换器,不用为每个配置类单独写转换逻辑:
using AutoMapper; public class CommonSettingsConverter<T> : ITypeConverter<IList<SettingsDb>, T> where T : new() { public T Convert(IList<SettingsDb> source, T destination, ResolutionContext context) { var result = new T(); if (source == null || !source.Any()) return result; var configDict = source.ToDictionary(x => x.Name, x => x.Value); // 反射获取目标类型所有可写属性 var properties = typeof(T).GetProperties().Where(p => p.CanWrite); foreach (var prop in properties) { if (!configDict.TryGetValue(prop.Name, out var valueStr) || string.IsNullOrEmpty(valueStr)) continue; // 自动把字符串转为属性对应类型 var convertedValue = Convert.ChangeType(valueStr, prop.PropertyType); prop.SetValue(result, convertedValue); } return result; } }
配置时直接指定泛型参数即可:
CreateMap<IList<SettingsDb>, FtpSettings>().ConvertUsing<CommonSettingsConverter<FtpSettings>>(); CreateMap<IList<SettingsDb>, SmtpSettings>().ConvertUsing<CommonSettingsConverter<SmtpSettings>>();
内容的提问来源于stack exchange,提问作者lunatic84
相关产品推荐
相关产品推荐

