如何使用自动映射器映射 child 并使用
How to map a child with automapper and convert using
我正在使用自动映射器从模型映射到 dto。在我的模型中,我想使用一个字符串,而在我的 dto 中我使用一个枚举。虽然它是嵌套的 child,但我使用的是 ForPath 而不是 ForMember。转换为字符串很容易,但是要将字符串转换回类型我写了一个 ValueConverter。将 ValueConverter 与 ForMember 结合使用效果很好,但是现在我需要将它与 ForPath 一起使用,这是不可能的。是否有任何其他解决方案可以解决此问题,而我在自动映射器文档或堆栈中找不到它。
这是我的 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;
}
}
感谢 Lucian Bargaoanu,我想出了这个解决方案。我将 valueConverter 重写为静态 class 并使用 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()));
与使用 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))
;
}
}
我正在使用自动映射器从模型映射到 dto。在我的模型中,我想使用一个字符串,而在我的 dto 中我使用一个枚举。虽然它是嵌套的 child,但我使用的是 ForPath 而不是 ForMember。转换为字符串很容易,但是要将字符串转换回类型我写了一个 ValueConverter。将 ValueConverter 与 ForMember 结合使用效果很好,但是现在我需要将它与 ForPath 一起使用,这是不可能的。是否有任何其他解决方案可以解决此问题,而我在自动映射器文档或堆栈中找不到它。
这是我的 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;
}
}
感谢 Lucian Bargaoanu,我想出了这个解决方案。我将 valueConverter 重写为静态 class 并使用 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()));
与使用 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))
;
}
}