You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:15:02