在automapper中使用命名约定和前缀的问题

时间:2017-04-19 13:35:07

标签: c# automapper

我设置了一个简单的控制台应用程序,我试图转换:

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

要:

public class user_dto
{
    public string ud_first_name { get; set; }
    public string ud_lastname { get; set; }
}

然后将它们转换为返回。这是我的尝试:

public static class AutoMapperConfig
{
    public static void RegisterMappings()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.RecognizeDestinationPrefixes(new []{"ud_"});
            cfg.RecognizePrefixes(new[] { "ud_" });
            cfg.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention();
            cfg.SourceMemberNamingConvention = new PascalCaseNamingConvention();

            cfg.CreateMap<User, user_dto>().ReverseMap();
        });
    }
}

static void Main(string[] args)
{
    AutoMapperConfig.RegisterMappings();

    var newUser = new User
    {
        FirstName = "John",
        LastName = "Doe"
    };

    var newUser2 = new user_dto
    {
        ud_first_name = "Marry",
        ud_lastname = "Jane"
    };

    var newUserDTO = AutoMapper.Mapper.Map<user_dto>(newUser);

    Console.Write(newUserDTO.ud_first_name + " " + newUserDTO.ud_lastname);

    var newUserViewModel = AutoMapper.Mapper.Map<User>(newUser2);

    Console.Write(newUserViewModel.FirstName + " " + newUserViewModel.LastName);
    Thread.Sleep(100);
}

这适用于转换姓氏,但不能转换名字。根据{{​​3}}设置的命名约定,我应该将其转换为first_name - &gt; FirstName,但它无声地失败,只转换了lastname

有趣的是,如果我删除配置中的前缀行并从ud_删除前导user_dto并运行应用程序,则会转换John Doe的全名,但仅限Marry的姓氏被转换。您是否无法删除prefixis并使用命名约定与automapper进行转换?是否应该有一种不同的/更好的方式来实现我尝试的目标?

2 个答案:

答案 0 :(得分:2)

我不知道您是否能够更改dto中属性的名称,但是如果可以的话,它似乎在版本4.2.1或AutoMapper中可以正常使用下划线。

public class user_dto
{
    public string ud_firstname { get; set; }
    public string ud_lastname { get; set; }
}

输出:

John DoeMary Jane

我猜想AutoMapper会对下划线的数量感到困惑,这就是为什么当您删除ud_部分时它部分有效

更新:

这感觉不对,但确实有效,所以在这种情况下也许是一种解决方法。将以下行添加到配置中以允许在完成自动映射后进行自定义映射。

cfg.CreateMap<User, user_dto>().ReverseMap().AfterMap((src, dest) => dest.FirstName = src.ud_first_name);
cfg.CreateMap<user_dto, User>().ReverseMap().AfterMap((src, dest) => dest.ud_first_name = src.FirstName);

完整配置类:

public static class AutoMapperConfig
{
    public static void RegisterMappings()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.RecognizeDestinationPrefixes(new []{"ud_"});
            cfg.RecognizePrefixes(new[] { "ud_" });
            cfg.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention();
            cfg.SourceMemberNamingConvention = new PascalCaseNamingConvention();
            cfg.CreateMap<User, user_dto>().ReverseMap().AfterMap((src, dest) => dest.FirstName = src.ud_first_name);
            cfg.CreateMap<user_dto, User>().ReverseMap().AfterMap((src, dest) => dest.ud_first_name = src.FirstName);
        });
    }
}

答案 1 :(得分:2)

以下按预期方式工作:

Mapper.Initialize(cfg =>
    {
        cfg.CreateProfile("UserViewModelToDto", prf =>
        {
            prf.RecognizeDestinationPrefixes(new[] { "ud" });
            prf.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention();
            prf.CreateMap<User, user_dto>();
        });

        cfg.CreateProfile("UserDtoToViewModel", prf =>
        {
            prf.RecognizePrefixes(new[] { "ud_" });
            prf.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
            prf.CreateMap<user_dto, User>();
        });
    });