如何使用automapper映射一个子代,并使用转换。

问题描述 投票:0回答:1

我正在使用automapper从模型映射到dto。在我的模型中,我想使用一个字符串,而在我的dto中,我使用一个Enum。虽然它是一个嵌套子代,但我使用ForPath代替ForMember。转换为字符串很容易,但是要把字符串转换回类型,我写了一个ValueConverter。将ValueConverter与ForMember结合使用效果很好,但是现在我需要将它与ForPath结合使用,这是不可能的。有没有其他的解决方案来解决这个问题,而我在automapper文档或堆栈中找不到。

这是我的MappingProfile,这部分是和成员一起工作的。

CreateMap<Dto, Model>()
            .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.Type.ToString()))
            .ReverseMap()
            .ForMember(dest => dest.Type, opt => opt.ConvertUsing(new StringToEnumConverter<Type>(), src => src.Type));

这部分我需要ForPath和ConvertUsing,这段代码是不允许的。

    CreateMap<Dto, Model>()
            .ForPath(dest => dest.Type, opt => opt.MapFrom(src => src.Parent.Type.ToString()))
            .ReverseMap()
            .ForPath(dest => dest.Parent.Type, opt => opt.ConvertUsing(new StringToEnumConverter<Type>(), src => src.Type));

这是我的ValueConverter。

public class StringToEnumConverter<T> : IValueConverter<string, T> where T : struct
{
    public T Convert(string source, ResolutionContext context)
    {
        if (!string.IsNullOrEmpty(source))
        {
            if (Enum.TryParse(source, out T result))
            {
                return result;
            }
        }

        return default;
    }
}
c# asp.net-core automapper
1个回答
1
投票

感谢Lucian Bargaoanu,我想出了这个解决方案。我重写了valueConverter,使其成为一个静态类,并使用MapFrom来转换。

 public static class StringEnumExtension
{
    public static TaskType ToTaskType(this string source)
    {
        return ToEnum<TaskType>(source);
    }

    public static TaskQuestionType ToTaskQuestionType(this string source)
    {
        return ToEnum<TaskQuestionType>(source);
    }

    private static T ToEnum<T>(string source) where T : struct
    {
        if (!string.IsNullOrEmpty(source))
        {
            if (Enum.TryParse(source, out T result))
            {
                return result;
            }
        }

        return default;
    }
}

我更新了这样的映射。

CreateMap<TaskDto, TaskModel>()
            .ForPath(dest => dest.TaskType, opt => opt.MapFrom(src => src.TaskDefinition.TaskType.ToString()))
            .ReverseMap()
            .ForPath(dest => dest.TaskDefinition.TaskType, opt => opt.MapFrom(src => src.TaskType.ToTaskType()));

0
投票

我更喜欢在同一个配置文件中使用额外的映射,而不是使用... ... ForPath. 这样我仍然可以使用我的自定义值解析器。

public class DstObject
{
    public int AnotherProperty { get; set; }
    public DstChildObject DstChildObject { get; set; }
}

public class DstChildObject
{
    public string SomeProperty { get; set; }      
}

public class MyMappingProfile : Profile
{
    public MyMappingProfile()
    {
        this.CreateMap<SourceType, DstObject>()
            .ForMember(dst => dst.AnotherProperty, opt => opt.MapFrom(src => src.AnotherProperty))
            .ForMember(dst => dst.DstChildObject, opt => opt.MapFrom(src => src))
            ;

        this.CreateMap<SourceType, DstChildObject>()
            .ForMember(dst => dst.SomeProperty, opt => opt.MapFrom(src => src.SomeProperty))
            ;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.