AutoMapper - ReverseMap 中的 IValueConverter 问题

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

我正在尝试使用带有自定义值转换器的 AutoMapper 在两个类

ParentA
ParentB
之间进行映射。但是,从
ParentB
映射回
ParentA
时,我遇到了问题。

我们使用 AutoMapper 属性来进行映射。

这是我的代码:

ParentA ssssssss = new ParentA { Id = 1, isActive = "Y", Name = "test" };
var response = automapper.Map<ParentB>(ssssssss);
response.Value = 500;
var yyyy = automapper.Map<ParentA>(response);

类定义:

public class ParentA
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string isActive { get; set; }
}

[AutoMap(typeof(ParentA), ReverseMap = true)]
public class ParentB
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ValueConverter(typeof(IntConverter))]
    [SourceMember("isActive")]
    public int Value { get; set; } 
}

转换器:

public class IntConverter : IValueConverter<string, int>
{
    public int Convert(string sourceMember, ResolutionContext context)
    {
        if (sourceMember == "Y") return 100;
        if (sourceMember == "N") return 200;
        if (sourceMember == "P") return 500;
        return 1000;
    }
 
    public string Convert(int sourceMember, ResolutionContext context)
    {
        throw new NotImplementedException();
    }
}

ParentA
ParentB
的映射工作正常。

ParentB
映射回
ParentA
时,失败,因为
Convert
中反向映射的
IntConverter
方法未实现。

你能帮我实现

IValueConverter
中的反向映射吗?

c# asp.net-core automapper
2个回答
2
投票

经过一些尝试和错误,我认为基于属性的映射在使用值转换器执行反向映射时存在一些局限性。

Value Converter 的实现仅支持单向映射。

因此,建议从

ReverseMap = true
属性中删除
[AutoMap]
。您应该将
[AutoMap]
属性应用于
ParentB
类,并将
[SourceMember]
[ValueConverter]
属性应用于
isActive
属性。

[AutoMap(typeof(ParentB))]
public class ParentA
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ValueConverter(typeof(StringConverter))]
    [SourceMember("Value")]
    public string isActive { get; set; }
}

[AutoMap(typeof(ParentA))]
public class ParentB
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ValueConverter(typeof(IntConverter))]
    [SourceMember("isActive")]
    public int Value { get; set; }
}

public class StringConverter : IValueConverter<int, string>
{
    public string Convert(int sourceMember, ResolutionContext context)
    {
        
        if (sourceMember == 100)
            return "Y";
        if (sourceMember == 200)
            return "N";
        if (sourceMember == 500)
            return "P";
        return null;
    }
}

否则,您应该使用 Fluent 配置(

Profile
和/或
MappingConfiguration
)来为
Value
/
isActive
属性提供反向映射的映射规则。

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<ParentA, ParentB>()
            .ForMember(dest => dest.Value, opt => opt.ConvertUsing(new IntConverter(), src => src.isActive))
            .ReverseMap()
            .ForMember(dest => dest.isActive, opt => opt.ConvertUsing(new StringConverter(), src => src.Value));
    }
}

1
投票

这个怎么样:

public class IntConverter : IValueConverter<string, int>
{
    public int Convert(string sourceMember, ResolutionContext context)
    {
        if (sourceMember == "Y") return 100;
        if (sourceMember == "N") return 200;
        if (sourceMember == "P") return 500;
        return 1000;
    }
 
    public string Convert(int sourceMember, ResolutionContext context)
    {
        if (sourceMember == 100) return "Y";
        if (sourceMember == 200) return "N";
        if (sourceMember == 500) return "P";
        return "your default";
    }
}

但这似乎是显而易见的。您一定还有其他问题吗?

© www.soinside.com 2019 - 2024. All rights reserved.