Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用automapper映射子对象并使用_C#_Asp.net Core_Automapper - Fatal编程技术网

C# 如何使用automapper映射子对象并使用

C# 如何使用automapper映射子对象并使用,c#,asp.net-core,automapper,C#,Asp.net Core,Automapper,我使用automapper从模型映射到dto。在我的模型中,我想使用一个字符串,而在我的数据中,我想使用一个枚举。虽然它是嵌套的子对象,但我使用的是ForPath而不是FormMember。转换为字符串很容易,但是要将字符串转换回类型,我编写了一个ValueConverter。将ValueConverter与FormMember结合使用效果非常好,但是现在我需要将其与ForPath结合使用,这是不可能的。当我在automapper文档或堆栈中找不到它时,是否有其他解决方案来解决这个问题 这是我的

我使用automapper从模型映射到dto。在我的模型中,我想使用一个字符串,而在我的数据中,我想使用一个枚举。虽然它是嵌套的子对象,但我使用的是ForPath而不是FormMember。转换为字符串很容易,但是要将字符串转换回类型,我编写了一个ValueConverter。将ValueConverter与FormMember结合使用效果非常好,但是现在我需要将其与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));
CreateMap()
.FormMember(dest=>dest.Type,opt=>opt.MapFrom(src=>src.Type.ToString())
.ReverseMap()
.ForMember(dest=>dest.Type,opt=>opt.ConvertUsing(new-StringToEnumConverter(),src=>src.Type));
这部分我需要为路径和转换使用,这段代码是不允许的

    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));
CreateMap()
.ForPath(dest=>dest.Type,opt=>opt.MapFrom(src=>src.Parent.Type.ToString())
.ReverseMap()
.ForPath(dest=>dest.Parent.Type,opt=>opt.ConvertUsing(new StringToEnumConverter(),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;
    }
}
公共类StringToEnumConverter:IValueConverter其中T:struct
{
公共T转换(字符串源、ResolutionContext上下文)
{
如果(!string.IsNullOrEmpty(源))
{
if(枚举TryParse(源,输出结果))
{
返回结果;
}
}
返回默认值;
}
}

多亏了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;
    }
}
公共静态类StringEnumExtension
{
公共静态任务类型ToTaskType(此字符串源)
{
返回ToEnum(源);
}
公共静态TaskQuestionType ToTaskQuestionType(此字符串源)
{
返回ToEnum(源);
}
私有静态T ToEnum(字符串源),其中T:struct
{
如果(!string.IsNullOrEmpty(源))
{
if(枚举TryParse(源,输出结果))
{
返回结果;
}
}
返回默认值;
}
}
我更新了地图,如下所示:

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()));
CreateMap()
.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))
            ;
    }
}
公共类对象
{
公共int其他属性{get;set;}
公共DstChildObject DstChildObject{get;set;}
}
公共类对象
{
公共字符串SomeProperty{get;set;}
}
公共类MyMappingProfile:Profile
{
公共MyMappingProfile()
{
这个
.ForMember(dst=>dst.AnotherProperty,opt=>opt.MapFrom(src=>src.AnotherProperty))
.ForMember(dst=>dst.dstchillobject,opt=>opt.MapFrom(src=>src))
;
这个
.FormMember(dst=>dst.SomeProperty,opt=>opt.MapFrom(src=>src.SomeProperty))
;
}
}

通过为内部对象创建映射,您始终可以避免路径问题。@LucianBargaoanu但如果它不是两个单独的对象,这是不可能的那么什么是
Parent
?@LucianBargaoanu我们可以映射两个父对象,但是我们只需要父对象中的一个属性,而不需要完整的父对象,因此我们选择使用ForPath,否则我们必须在我们的模型中使用很多属性。所以在模型中,它不是一个单独的对象,只有一个属性
ForPath
不支持转换器(除非您想自己实现)。因此,您要么使用
MapFrom
,要么删除
ForPath