iT邦幫忙

2022 iThome 鐵人賽

DAY 10
1
Software Development

ASP.NET Core 30 天旅程系列 第 10

[Day10]- AutoMapper 類別轉換(1)

  • 分享至 

  • xImage
  •  

上一篇我們有提到頁面傳入 Model 為 DTO,Service 回傳 ViewModel。
https://ithelp.ithome.com.tw/upload/images/20220925/20152200CEElwJLL4h.png

類別的對應轉換時常是一件很麻煩的事。例如下圖

public IEnumerable<UserViewModel> GetUser(UserDTO m)
{

    var data = GetUserByAccName(m);
    var result = data.Select(x => new UserViewModel()
    {
        Name = x.Name,
        Account = x.Account,
        Email = x.Email,
        Role = x.Role,
        Note = x.Note,
    });
    return result;
}

或者是

public IEnumerable<UserViewModel> GetUser(UserDTO m)
{

    var data = GetUserByAccName(m);
    List<UserViewModel> result = new List<UserViewModel>();
    foreach (var i in data)
    {
        UserViewModel viewModel = new UserViewModel();
        viewModel.Name = i.Name;
        viewModel.Account = i.Account;
        viewModel.Email = i.Email;
        viewModel.Role = i.Role;
        viewModel.Note = i.Note;
        result.Add(viewModel);
    }

    return result;
}

有沒有覺得,這樣的轉換非常麻煩,而且上面的範例只有五個欄位的轉換,如果今天是十個或者更多,那應該是非常得眼花撩亂,這時候就要介紹強大的AutoMapper

AutoMapper

  • 官網
  • NuGet 安裝:Install-Package AutoMapper

AutoMapper的使用很簡單,就三個步驟
1.設定 Model 之間的轉換
2.建立 Mapper
3.透過 Map 方法轉換型別

public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
    var data = GetUserByAccName(m);

    var config = new MapperConfiguration(cfg =>
        cfg.CreateMap<UserDTO, UserViewModel>()); 
    var mapper = config.CreateMapper(); 
    var result = mapper.Map<IEnumerable<UserViewModel>>(data); 

    return result;
}

有沒有發現程式碼行數不但變少了,整個程式碼看起來也很好懂!但你可能會疑惑,他是如何對應的呢?

AutoMapper 會將兩個類別相同名稱的屬性內容做轉換

自訂轉換

那如果今天名稱不同,又或者是要合併顯示該如何處理呢?
*假設我的 ViewModel 的 Name 想要帳號+空白+名字

public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
    var data = GetUserByAccName(m);

    var config = new MapperConfiguration(cfg =>
        cfg.CreateMap<UserDTO, UserViewModel>()
        .ForMember(x => x.Name, y => y.MapFrom(o => $"{o.Account} {o.Name}")));
    var mapper = config.CreateMapper();
    var result = mapper.Map<IEnumerable<UserViewModel>>(data);

    return result;
}

Ignore 欄位

有時候我們會遇到沒有對應的欄位,例如 資料回來的 ViewModel 有 LoginTime 欄位,但傳入的 DTO 沒有,這時候如果用上面的方法,會造成轉換錯誤,所以我們必須 Ignore LoginTime欄位

public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
    var data = GetUserByAccName(m);

    var config = new MapperConfiguration(cfg =>
        cfg.CreateMap<UserDTO, UserViewModel>()
        .ForMember(x => x.Account, y => y.MapFrom(o => $"{o.Account} {o.Name}"))
        .ForMember(x => x.LoginTime, y => y.Ignore())); //忽略掉不轉換
    var mapper = config.CreateMapper();
    var result = mapper.Map<IEnumerable<UserViewModel>>(data);

    return result;
}

到這邊你可能會疑惑,怎麼感覺越來越多行了,那所謂的簡化呢?不要急,我們下一篇來介紹

  • 如何使用 Profile 將對應關係集中起來方便管理,也會讓程式碼看起來更簡潔
  • .NET Core 中依賴注入(DI)AutoMapper

參考資料

那今天就到這邊囉,大家明天見!


上一篇
[Day09]- .NET Core MVC 架構規劃(範例篇)
下一篇
[Day11]- AutoMapper 類別轉換(2)
系列文
ASP.NET Core 30 天旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言