天天看點

net Core 使用AutoMapper

資料庫的實體模型和視圖模型進行分離

資料庫持久化對象(Persistent Object):顧名思義,這個對象是用來将我們的資料持久化到資料庫,一般來說,持久化對象中的字段會與資料庫中對應的 table 保持一緻。

視圖對象(View Object):視圖對象 VO 是面向前端使用者頁面的,一般會包含呈現給使用者的某個頁面/元件中所包含的所有資料字段資訊。

資料傳輸對象(Data Transfer Object):資料傳輸對象 DTO 一般用于前端展示層與背景服務層之間的資料傳遞,以一種媒介的形式完成 資料庫持久化對象 與 視圖對象 之間的資料傳遞。

NuGet

通過 NuGet 安裝 AutoMapper 的包。

AutoMapper 
AutoMapper.Extensions.Microsoft.Dependencylnjection
      

配置對象轉換

建立MappingProfile繼承抽象類 Profile

using AutoMapper;
using Snblog.Models;
using System;
using System.Collections.Generic;
using System.Text;

namespace Snblog.Enties.AutoMapper
{
    public class MappingProfile : Profile
    {
        /// <summary>
        /// 配置構造函數,用來建立關系映射
        /// </summary>
        public MappingProfile()
        {
            //建構實體映射規則添加映射對象  
            //如兩個實體字段一緻可直接映射關系
            //SnUser原對象類型,SnUserDto 目标對象類型  ReverseMap,可互相轉換
            CreateMap<SnUser, SnUserDto>().ReverseMap(); 
            //CreateMap<SnUser, SnUserDto>();
            //CreateMap<SnUserDto, SnUser>();
        }
    }
}

      

表實體

在轉化的時候隻有名字相同的字段才會成功附上對應的值。

資料庫實體

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Snblog.Models
{
    public partial class SnUser
    {
        public int UserId { get; set; }
        public string UserIp { get; set; }
        public string UserName { get; set; }
        public string UserEmail { get; set; }
        public string UserPwd { get; set; }
        public string UserPhoto { get; set; }
        public string UserTime { get; set; }
        public string UserNickname { get; set; }
        public string UserBrief { get; set; }
    }
}

      

視圖模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Snblog.Models
{
    public partial class SnUserDto
    {
        public int UserId { get; set; }
        public string UserIp { get; set; }
        public string UserName { get; set; }
        public string UserEmail { get; set; }
        public string UserPwd { get; set; }
        public string UserPhoto { get; set; }
        public string UserTime { get; set; }
        public string UserNickname { get; set; }
        public string UserBrief { get; set; }
    }
}

      

注冊服務

#region 實體映射
            services.AddAutoMapper(typeof(MappingProfile));
            #endregion
      

自動化注冊 1

//自動化注冊
            //Assembly.Load() 裡面傳的是目前項目的名稱,或者類庫的名稱。擷取目前項目下的所有類檔案。
            //通過 Lamda 表達式 Where 找到所有以 Mapper 結尾的檔案。
            //這樣就可以自動注冊項目内的所有 Mapper 檔案了。
            services.AddAutoMapper(
               Assembly.Load("Snblog.Enties").GetTypes()
                   .Where(t => t.FullName.EndsWith("Mapper"))
                   .ToArray()
           );
      

自動化注冊 2

添加接口類 IProfile

public interface IProfile
    {

    }
      

在所有的 Mapper 類裡面,實作這個接口。

public class UserMapper : Profile, IProfile
    {
        public UserMapper()
        {
            CreateMap<UserDto, User>();
            CreateMap<User, UserViewModel>()
                .BeforeMap((u, v) => u.Remark = "Good")
                .ForMember(v => v.DepartmentId, u => u.MapFrom(user => user.DepartmentId))
                .ForMember(v => v.DepartmentName, u => u.MapFrom(user => user.DepartmentInfo.Name))
                .AfterMap((u, v) => u.Age++);
        }
    }
      

再通過查找所有實作了 IProfile 接口的類,就可以找到所有的 Mapper 對象。

( Profile 是 AutoMapper 元件裡的接口,必須自定義項目中的唯一标記。)

建立 MapperRegister 類,實作擷取所有的 Mapper 對象。

public class MapperRegister
    {
        /// <summary>
        /// 通過反射自動化注冊
        /// </summary>
        /// <returns></returns>
        public static Type[] MapType()
        {
            Assembly ass = Assembly.GetAssembly(typeof(IProfile));
            Type[] types = ass.GetTypes();

            List<Type> allList = new List<Type>();

            foreach (Type item in types)
            {
                if (item.IsInterface) continue;//判斷是否是接口
                Type[] ins = item.GetInterfaces();
                foreach (Type ty in ins)
                {
                    if (ty == typeof(IProfile))
                    {
                        allList.Add(item);
                    }
                }
            }
            Type[] alltypes = allList.ToArray();
            return alltypes;
        }

    }
      

修改 StrartUp 類,調整注冊方式。

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            //services.AddAutoMapper(typeof(UserMapper));
            //自動化注冊
            services.AddAutoMapper(MapperRegister.MapType());

        }
      

這樣就可以每次添加 Mapper 類的時候,隻需要添加 IProfile 标記,就可以自動注冊了。

應用

入參控制好 Add/Up Dto 轉資料實體。

傳回參數 資料實體轉Dto

// 建立一個字段來存儲mapper對象
  private readonly IMapper _mapper;

   public SnUserService(IMapper mapper)
        {
            _service = service;
            _mapper = mapper;
        }
       //更新-轉資料實體
       var model = _mapper.Map<SnUser>(user);
       int da = await CreateService<SnUser>().UpdateAsync(model);

       //查詢- 資料庫實體轉Dto
       public async Task<List<SnUserDto>> AsyGetUser()
        {
            var user = await  _service.SnUser.ToListAsync();
            return _mapper.Map<List<SnUserDto>>(user); 
        }