從零開始的.NET專案(一)倉儲模式與配置AutoMapper

有了一个点子發表於2024-06-06

目標框架:.net6.0

作業系統:mac os

編譯器:Rider

內容:建立第一個Controller,使用倉儲(Respository)模式實現,並使用AutoMapper進行資料物件關係對映

非常簡單的實現,Automapper也只介紹了最基礎也最常用的 其他用法後續再補,目的就是穩準狠🤪

(一)倉儲層

IxxxRepository

建立IxxxRepository.cs介面類,定義對資料操作的契約。

namespace xxx;

public interface IxxxRepository
{
    IEnumerable<YourModel> getData();

    YourModel getDataById(Guid id);
}

xxxRepository

建立xxxRepository.cs

namespace xxx;

public class xxxRepository : IxxxRepository
{
    private readonly AppDBContext _context;

    public xxxRepository(AppDBContext context)
    {
        _context = context;
    }

    public IEnumerable<YourModel> getData()
    {
        return _context.YourModels;
    }

    public YourModel getDataById(Guid id)
    {
        return _context.YourModels.FirstOrDefault();
    }
}

(二)AutoMapper

AutoMapper其實是先掃描程式集目錄中所有的profile檔案,以此來建立對映關係,所以我們要先建立相關Dto類,來告訴AutoMapper如何對映。

Dto

public class YourModel
{
    public string Id { get; set; }

    public string Name { get; set; }  

    public int Sum { get; set; }
}

資料庫Model

public class YourModel
{
    [Key] 
    public Guid Id { get; set; }

    [Required]
    public string Name { get; set; }  

    public int A { get; set; }

    public int B { get; set; }
}

profile

AutoMapper優先會把同名的欄位相互對映,但有些時候我們想要對映的欄位資料型別不一致,或者想要多個欄位處理後再返回。

比如上面的,資料庫儲存的IdGuid型別,但想要返回的資料中,Idstring型別,Sum欄位為A + B。具體實現如下

namespace xxx;

public class xxxProfile : Profile
{
    public xxxProfile()
    {
        CreateMap<YourModel, xxxDto>()
            .ForMember(dest => dest.Price,
                opt => opt.MapFrom(src => src.A * B)))
            .ForMember(dest => dest.DepartureCity,
                opt => opt.MapFrom(src => src.Id.ToString()));
    }
}

(三)注入服務

Program.cs新增服務,這裡筆者新增的是瞬時(Transient)服務。

builder.Services.AddTransient<IxxxRepository, xxxRepository>();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

(四)Controller

namespace xxx;

[Route("api/[controller]")] 
[ApiController]
public class xxxController : ControllerBase
{
    private IxxxRepository _xxxRepository;
    private readonly IMapper _mapper;

    public TouristRoutesController(IxxxRepository xxxRepository, IMapper mapper)
    {
        _xxxRepository = xxxRepository;
        _mapper = mapper;
    }

    /// <summary>
    /// 獲取資料
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public IActionResult GetData()
    {
        var data = _xxxRepository.getData();

        var xxxDto = _mapper.Map<IEnumerable<YourDto>>(data);
        if (xxxDto == null || xxxDto.Count() < 0)
        {
            return NotFound("無資料");
        }

        return Ok(dtoData);
    }

    /// <summary>
    /// 透過id查詢資料
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("{id:guid}")]
    // api/touistroutes/{id}
    public IActionResult GetDataById(Guid id)
    {
        var data = _xxxRepository.getDataById(id);
        
        //使用mapper對映
        var xxxDto = _mapper.Map<YourDto>(data);
        if (xxxDto == null)
        {
            return NotFound("無資料");
        }

        return Ok(xxxDto);
    }
}

相關文章