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

AutoMapper映射JSON字符串到IEnumerable<string>时出现类型映射错误

问题:AutoMapper映射JSON字符串到IEnumerable失败的原因与解决方法

背景信息

领域模型

public class UserRoles : AggregateRoot<Guid>
{
    public string Email { get; private set; }
    public IEnumerable<string> Roles { get; private set; }

    public UserRoles(Guid id, string email, IEnumerable<string> roles) : base(id)
    {
        Email = email;
        Roles = roles;
    }
}

数据库实体(PostgreSQL jsonb存储)

角色信息在PostgreSQL中以jsonb类型存储为JSON字符串,对应的数据库实体:

public class UserRolesEntity
{
    public Guid Id { get; set; }
    public string Email { get; set; } = null!;
    public string Roles { get; set; } = null!;
}

数据库中Roles字段的存储示例:

["administrator", "engineer", "manager"]

仓储实现(EF Core + ABP IObjectMapper)

使用EntityFrameworkCore操作数据库,通过ABP框架的IObjectMapper(底层基于AutoMapper)实现数据库实体到领域模型的转换:

public class UserRolesRepository : IUserRolesRepository
{
    private readonly IamDbContext _iamDbContext;
    private readonly IObjectMapper _objectMapper;

    public UserRolesRepository(...)
    {...}

    public async Task<UserRoles?> GetByEmailAsync(string email, CancellationToken...)
    {
        var dbEntity = await _iamDbContext.UserRolesList
            .SingleOrDefaultAsync(x => x.Email == email, cancellationToken);

        if (dbEntity == null)
        {
            return null;
        }

        return _objectMapper.Map<UserRolesEntity, UserRoles>(dbEntity);
    }
}

AutoMapper映射配置

配置值解析器将JSON字符串反序列化为IEnumerable<string>:

public class DbEntityToDomainModelProfile : Profile
{
    public DbEntityToDomainModelProfile()
    {
        CreateMap<UserRolesEntity, UserRoles>()
            .ForMember(dest => dest.Roles, opt => opt.MapFrom<JsonStringToUserRolesResolver>())
            .Ignore(dest => dest.ConcurrencyStamp)
            .Ignore(dest => dest.ExtraProperties)
            .DisableCtorValidation();
    }
}

public class JsonStringToUserRolesResolver : IValueResolver<UserRolesEntity, UserRoles, IEnumerable<string>>
{
    public IEnumerable<string> Resolve(UserRolesEntity source, UserRoles dest, 
        IEnumerable<string> destMember, ResolutionContext context)
    {
        // System.Text.Json
        var userRoles = JsonSerializer.Deserialize<IEnumerable<string>>(source.Roles);
        if (userRoles == null)
        {
            return Enumerable.Empty<string>();
        }

        return userRoles;
    }
}

问题现象

运行时抛出以下异常:

AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

Mapping types:
String -> IEnumerable`1
System.String -> System.Collections.Generic.IEnumerable`1

临时解决方法

修改UserRoles领域模型,添加私有无参构造函数,并将构造函数中的roles参数重命名为roleList后,问题消失:

public class UserRoles : AggregateRoot<Guid>
{
    ...

    private UserRoles() { }

    public UserRoles(Guid id, string email, IEnumerable<string> roleList) : base(id)
    {
        Email = email;
        Roles = roleList;
    }
}

需求

请解释该错误的根本原因,并提供符合领域驱动设计规范的正确解决方式。


内容的提问来源于stack exchange,提问作者David Liang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:56:07