自动映射,按命名约定映射

时间:2018-05-08 09:13:37

标签: c# .net automapper

我使用automapper来映射我的实体。但实体有不同的结构。

来源:

public class SourceEntity
{
    public string Name { get; set; }
    public Type Type { get; set; }
    public Communication SelectedCommunication { get; set; }
}

public enum Type
{
    Type1=1,
    Typ2
}

[Flags]
public enum Communication
{
    Phone =1,
    Email =2,
    Post =4
}

我还有HasFlag()扩展方法,如果选择了flag,它将返回true。

目标实体:

public class DestinationEntity
{
    public string Name { get; set; }
    public bool Type1_PhoneSelected { get; set; }
    public bool Type1_EmailSelected { get; set; }
    public bool Type1_PostSelected { get; set; }
    public bool Type2_PhoneSelected { get; set; }
    public bool Type2_EmailSelected { get; set; }
    public bool Type2_PostSelected { get; set; }
}

我的地图:

        CreateMap<SourceEntity, DestinationEntity>()
            .ForMember(v => v.Name, opt => opt.MapFrom(i => i.Name));

但我无法找出映射类型属性的最佳方法。 是否可以在不输入类似内容的情况下进行映射:

.ForMemeber(v=>v.Test1_PhoneSelected, opt=>opt.MapFrom(i=>i.SelectedCommunication.HasFlag(Communication.Phone)))
.ForMemeber(v=>v.Test2_PhoneSelected, opt=>opt.MapFrom(i=>i.SelectedCommunication.HasFlag(Communication.Phone)))

对于每个属性。 有没有办法通过命名约定进行映射? 还是其他任何方式?

1 个答案:

答案 0 :(得分:1)

您可以使用custom value resolvers

  

尽管AutoMapper涵盖了相当多的目标成员映射   场景中,有1到5%的目标值需要a   解决问题的帮助很小。很多时候,这个自定义值解析   逻辑是域逻辑,可以直接在我们的域上。但是,如果   这个逻辑只适用于映射操作,它会混乱   我们的源类型有不必要的行为。在这些情况下,   AutoMapper允许为其配置自定义值解析器   目的地成员。

自定义值解析器的示例:

public class YourCustomResolver
    : IMemberValueResolver<object, object, Communication, bool>
{
    private Communication _communication;

    public YourCustomResolver(
        Communication communication)
    {
    }

    public bool Resolve(
        object source, 
        object destination,
        Communication sourceMember, 
        bool destMember, 
        ResolutionContext context)
    {
        return _communication == sourceMember;
    }
}

您的映射将如下所示:

CreateMap<SourceEntity, DestinationEntity>()
    .ForMember(dest => dest.Type1_PhoneSelected, opt => opt.ResolveUsing(new YourCustomResolver(Communication.Phone), src => src.SelectedCommunication))
    .ForMember(dest => dest.Type1_EmailSelected, opt => opt.ResolveUsing(new YourCustomResolver(Communication.Email), src => src.SelectedCommunication))
    .ForMember(dest => dest.Type1_PostSelected , opt => opt.ResolveUsing(new YourCustomResolver(Communication.Post) , src => src.SelectedCommunication))
    .ForMember(dest => dest.Type2_PhoneSelected, opt => opt.ResolveUsing(new YourCustomResolver(Communication.Phone), src => src.SelectedCommunication))
    .ForMember(dest => dest.Type2_EmailSelected, opt => opt.ResolveUsing(new YourCustomResolver(Communication.Email), src => src.SelectedCommunication))
    .ForMember(dest => dest.Type2_PostSelected , opt => opt.ResolveUsing(new YourCustomResolver(Communication.Post) , src => src.SelectedCommunication));