.Net Dto對(duì)象模型 與工具 AutoMapper

編輯于 2020/03/12

一. Dto是什么 '?'

DTO是Data Transfer Object 的簡(jiǎn)寫,既數(shù)據(jù)傳輸對(duì)象。
那viewModel和DTO又是什么關(guān)系呢?
viewModel更偏向于展示的數(shù)據(jù),而DTO是數(shù)據(jù)的傳輸,用于在服務(wù)器與客戶端之間或服務(wù)器與服務(wù)器之間進(jìn)行數(shù)據(jù)傳遞,實(shí)際上是不一樣的。

二. Dto的作用

DTO本身不是業(yè)務(wù)對(duì)象,他是根據(jù)UI需求進(jìn)行設(shè)計(jì)的。簡(jiǎn)單來說Model面向業(yè)務(wù),我們是通過后端業(yè)務(wù)來定義Model的。而DTO是面向UI,通過UI的需求來定義的,通過DTO我們實(shí)現(xiàn)了表現(xiàn)層與Model層之間的解耦,表現(xiàn)層不引用Model。如果開發(fā)過程中我們的模型變了,而界面沒變,我們只需改Model而不需要去改動(dòng)表現(xiàn)層。

三. 博主的理解

1.舉個(gè)例子,假設(shè)我本身就是個(gè)“對(duì)象模型”,我是個(gè)博主,.net程序員。這些信息是可以暴露出來的,就是dto傳輸?shù)膬?nèi)容,但是“我”這個(gè)對(duì)象模型不僅僅包含了這些信息,還有地址,電話。這些信息是我不想暴露出來的

2.再舉個(gè)例子,一個(gè)人的字段信息性別表示在數(shù)據(jù)庫為 null,0,1
在windows客戶端可能需要顯示“男人”
在ios端可能需要顯示“man”
在android端可能需要顯示“male”

有些字段我可能不想,也不需要發(fā)送給前端接收,有些字段我可能需要加工一下
這就可以通過Dto來實(shí)現(xiàn)

四. 實(shí)現(xiàn)的方式

環(huán)境

visual studio 2019
Core 3.1 WebApi

Models文件

實(shí)體類

public class GoodsEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public DateTime? CreateTime { get; set; }
    public bool IsDeleted { get; set; }
}

Dto類

public class GoodsDto
{
    public string GoodsName { get; set; }
    public decimal Price { get; set; }
    public string CreateTime { get; set; }
    public string Content { get; set; }
    public bool IsDeleted { get; set; }
}

可以發(fā)現(xiàn)Dto中3個(gè)變化
createTime字段變成了String
沒有Id字段
多了Content字段

1. 通過類與類屬性賦值來實(shí)現(xiàn)

Action方法

這種方式簡(jiǎn)單,但是當(dāng)是一個(gè)List時(shí),或者屬性很多時(shí),就會(huì)比較麻煩。

2. 通過AutoMapper實(shí)現(xiàn)

  1. 安裝AutoMapper
    使用nuget搜索AutoMapper安裝

    AutoMapper包

  2. 在Startup中添加AutoMapper

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        #region Automapper
        services.AddAutoMapper(typeof(Startup));
        #endregion
    }
    
  3. 創(chuàng)建AutoMapper映射規(guī)則,得告訴AutoMapper映射關(guān)系

    文件目錄

    AutoMapperConfigs.cs

    public class AutoMapperConfigs
    {
        public static MapperConfiguration RegisterMappings()
        {
            return new MapperConfiguration(cfg =>
            {
                cfg.AddProfile(new GoodsProfile());
            });
        }
    }
    

    GoodsProfile.cs

    // 添加你的實(shí)體映射關(guān)系.
    public class GoodsProfile : Profile
    {
        public GoodsProfile()
        {
            // GoodsEntity轉(zhuǎn)GoodsDto.
            CreateMap<GoodsEntity, GoodsDto>()
                // 映射發(fā)生之前
                // 映射之前統(tǒng)一處理
                .BeforeMap((ent, dto) => ent.Price = ent.Price + 10)
                // 默認(rèn)賦值
                .BeforeMap((src, dest) => src.CreateTime = src.CreateTime == null ? (new DateTime(2012, 12, 12)) : src.CreateTime)
    
    
                // 映射匹配   把GoodsEntity.Name匹配到GoodsDto.Name
                .ForMember(dto => dto.GoodsName, opt => opt.MapFrom(ent => ent.Name))
                .ForMember(dto => dto.CreateTime, opt => opt.MapFrom(ent => ((DateTime)ent.CreateTime).ToString("yyyy-MM-dd")))
                // 匹配的過程中賦值
                .ForMember(dto => dto.Price, opt => opt.MapFrom(ent => ent.Price + 10))
    
    
                // 映射發(fā)生之后
                .AfterMap((ent, dto) => dto.GoodsName = dto.Price < 40 ? "N/A." : dto.GoodsName)
                .AfterMap((src, dest) => dest.Content = "完成映射后");
    
    
            // 最簡(jiǎn)單的匹配,屬性字段/類型等完全一致
            // GoodsDto轉(zhuǎn)GoodsEntity.
            CreateMap<GoodsDto, GoodsEntity>();
        }
    }
    
  4. 在DtoController中修改添加代碼

    [HttpGet]
    [Route(nameof(GetGoods))]
    public ActionResult GetGoods()
    {
        ////實(shí)例化實(shí)體
        GoodsEntity goodsEntity = new GoodsEntity()
        {
            Id = 1,
            Name = "商品1",
            Price = 23.25M,
            CreateTime = DateTime.Now,
            IsDeleted = true,
        };
    
        var goodsDtos = _mapper.Map<GoodsDto>(goodsEntity);
        return Ok(goodsDtos);
    }
    
  5. 運(yùn)行后結(jié)果如下


    運(yùn)行結(jié)果

源碼鏈接

下載dtoAutoMapper分支即可

碼云

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容