Asp.net core 学习笔记 (AutoMapper)

参考 : 

http://www.cnblogs.com/xishuai/p/3700052.html

http://www.cnblogs.com/xishuai/p/3704435.html

http://www.cnblogs.com/xishuai/p/3708483.html

 

automapper 并不是 dotnet core 的东西啦,只是记入在这里而已.

automapper 是一个简单的库,帮我们处理对象和对象的映射. 

我们做开发通常会用到 ef core, 

entity 基本上对应 sql 的一个 table, 但是通常数据库的结构会比较复杂, 要范式,不要冗余嘛. 

但是呢,我们在做 view , 或者在 post, put resource 的时候往往不需要那么多和那么复杂的结构.

所以就有了 DTO , data transfer object 的概念. 

而 entity <-> DTO 就是一个很繁琐的映射. 于是就有了 automapper 这个比较智能的工具库.

 

nuget 安装 : AutoMapper.Extensions.Microsoft.DependencyInjection

在 service config 添加 services.AddAutoMapper();

定义一个 Profile (我的做法是把所有的映射都写在一起,一堆就是了,感觉比较容易找,遇到要添加 column 的情况下, 就有很多 dto 要跟着添加嘛)

    public class UserProfile : Profile
    {
        public UserProfile()
        {
            CreateMap<Member, MemberDto>();
        }
    }

 

1. 复杂类型到简单类型 

复制代码
public class Member {
    public Address address { get; set; }
}

public class Address {
    public string country { get; set; }
}

public class MemberDto {
    public string addressCountry { get; set; }
}
复制代码

两层变一层

复制代码
public class HomeController : Controller
{
    private readonly IMapper Mapper;
    public HomeController(
        IMapper mapper
    ) {
        Mapper = mapper;
    }
    public IActionResult Index()
    {
        var member = new Member { address = new Address { country = "Malaysia" } };
        var memberDto = Mapper.Map<MemberDto>(member);
        var result = memberDto.addressCountry; // Malaysia
        return View();
    }
}
复制代码

这样就可以了. 

 

2. 简单类型到复杂类型

用反转就可以了

CreateMap<Member, MemberDto>().ReverseMap();
// ReverseMap 是好东西, 但有些东西不能直接反转, 比如 ignore
CreateMap<Member, MemberDto>().ForMember(dest => dest.name, opt => opt.Ignore()).ReverseMap().ForPath(dest => dest.name, opt => opt.Ignore());
如果不写 ForPath 只有 to dto 的时候回 ignore.

 

3. 自定义映射

CreateMap<Member, MemberDto>().ForMember(dest => dest.addressCountry, opt => opt.MapFrom(sour => sour.address.country));

使用 ForMember + MapFrom 可以完全自己定义.

dest = destination 目的地, sour = source, automapper 就是 source -> destination 的概念.

 

4. ignore 无视

CreateMap<Member, MemberDto>().ForMember(dest => dest.name, opt => opt.Ignore()).ReverseMap().ForPath(dest => dest.name, opt => opt.Ignore());

 

5.collection 

不需要任何新配置

var members = Mapper.Map<List<Member>>(membersDto);

 

6.继承

继承是当我们有这样的需求的时候 

假设 Person -> Man -> Boy

var x = new Boy { propBoy = "da", propMan = "d", name = "a" };
var g = Mapper.Map<PersonDto>(x);

我们希望 g 是一个 BoyDto 

CreateMap<Person, PersonDto>().Include<Man, ManDto>().Include<Boy, BoyDto>();
CreateMap<Man, ManDto>();
CreateMap<Boy, BoyDto>();

需要如上的配置才行哦, 缺一不可. 

 

到这里我们可以看出来, automapper 的 config 主要就是针对, 当某个类型需要被映射到另一个类型时,它需要怎样的配置. 

 

7. 原始类型转换

既然是类型转换,那 string 可以 to int 映射吗 ? 

Mapper.CreateMap<string, int>().ConvertUsing(Convert.ToInt32);
Mapper.CreateMap<string, int>().ConvertUsing(stringValue => Convert.ToInt32(stringValue)); //表达式也可以

完全没有问题. 

refer : http://docs.automapper.org/en/latest/Custom-type-converters.html?highlight=custom

 

8. 值得映射

上面说到有时候我们需要些自定义的映射,那是因为它原始没有嘛。但是如果一直写重复也不行。

所以还是可以封装的. 

复制代码
public class UserProfile : Profile
{
    public UserProfile()
    {
        CreateMap<Source, Destination>()
            .ForMember(dest => dest.Total, opt => opt.MapFrom<CustomResolver>()));
    }
}

public class Source
{
    public int Value1 { get; set; }
    public int Value2 { get; set; }
}

public class Destination
{
    public int Total { get; set; }
}

public class CustomResolver : IValueResolver<Source, Destination, int>
{
    public int Resolve(Source source, Destination destination, int member, ResolutionContext context)
    {
        return source.Value1 + source.Value2;
    }
}
复制代码

真实场景下, 把 Source 和 Destination 换成接口.

refer : http://docs.automapper.org/en/latest/Custom-value-resolvers.html

 

9. default value 

  Mapper.CreateMap<Source, Destination>().ForMember(dest => dest.Value, opt => opt.NullSubstitute("Other Value"));

如果映射时 source 没有值,我们可以通过这里给一个 default 给 destination.

 

 

总结 : 

automapper 就是帮助我们写映射的. 我们使用的时候一定要记得这一点,不要让它去做超出范围的事情. 

 

posted @   兴杰  阅读(1152)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示