4. DBContext

4-8. APIController에서 ApplicationDbContext 사용

이 섹션에서는 .Net Core Web API에서 Entity Framework Core를 사용하여 데이터베이스와 상호 작용하는 방법을 배웁니다.

이 과정을 통해 임시 데이터 저장소를 실제 데이터베이스로 대체하는 방법을 학습합니다.

  1. PlantStore 제거: 이전에 사용하던 임시 데이터 저장소인 PlantStore는 더 이상 사용하지 않으므로 제거합니다.
  2. ApplicationDbContext 사용: API 컨트롤러에서 ApplicationDbContext 인스턴스를 사용하여 데이터베이스와의 상호 작용을 처리합니다. 이를 위해 ApplicationDbContext를 컨트롤러의 종속성 주입을 통해 주입받습니다.
  3. 데이터 조회 및 조작: Entity Framework Core를 사용하여 데이터베이스에서 데이터를 조회하고 조작하는 방법을 배웁니다. DbContextDbSet을 사용하여 CRUD(Create, Read, Update, Delete) 작업을 수행합니다.
    • 조회: DbContext.DbSet.ToList() 또는 FirstOrDefault() 메서드를 사용하여 데이터를 조회합니다.추가: DbContext.DbSet.Add() 메서드와 DbContext.SaveChanges()를 사용하여 데이터를 추가합니다.삭제: DbContext.DbSet.Remove() 메서드와 DbContext.SaveChanges()를 사용하여 데이터를 삭제합니다.업데이트: DbContext.DbSet.Update() 메서드와 DbContext.SaveChanges()를 사용하여 데이터를 업데이트합니다.
  4. Patch 작업 처리: HTTP PATCH 요청을 처리하는 경우, 변경할 필드만 포함된 JSON Patch 문서를 사용합니다. 이를 처리하기 위해 JsonPatchDocument를 사용하고, ApplyTo() 메서드를 통해 변경사항을 적용한 후 데이터베이스를 업데이트합니다.
  5. 코드 최적화: Entity Framework Core의 강력한 기능을 활용하여 데이터베이스 작업을 간소화하고 코드를 최적화합니다. 이 과정에서 데이터 모델과 DTO(Data Transfer Object) 간의 변환을 수행해야 할 수도 있습니다.
  6. 데이터베이스 마이그레이션: 데이터베이스 스키마 변경사항을 관리하기 위해 Entity Framework Core의 마이그레이션 기능을 사용합니다. 마이그레이션을 통해 데이터베이스 테이블을 생성하고 초기 데이터를 씨딩하는 작업을 코드 수준에서 처리합니다.

이 과정을 통해 개발자는 Entity Framework Core를 사용하여 .Net Core Web API 프로젝트에서 데이터베이스를 효율적으로 관리하고, API를 통해 데이터를 조작하는 방법을 배울 수 있습니다. 데이터베이스와의 상호 작용을 코드로 관리함으로써 데이터베이스 스키마 변경, 데이터 조작, 초기 데이터 씨딩 등의 작업을 보다 체계적이고 효율적으로 수행할 수 있습니다.

[Route("api/PlantAPI")]
[ApiController]
public class PlantAPIController : ControllerBase
{

    private readonly ApplicationDbContext _db;

    public PlantAPIController(ApplicationDbContext db)
    {
         _db = db;
    }

    [HttpGet]
    public ActionResult<IEnumerable<PlantDTO>> GetPlants()
    {
        return Ok(_db.Plants.ToList());
    }

    // 3-2. 응답 타입
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpGet("id:int")]
    public ActionResult<PlantDTO> GetPlant(int id)
    {
        if (id == 0)
        {
            return BadRequest();
        }

        //var plant = PlantStore.PlantList.FirstOrDefault(u => u.Id == id);
        // 조회 (단건)
        var plant = _db.Plants.FirstOrDefault(u => u.Id == id);            

        if (plant == null)
        {
            return NotFound();
        }
        
        return Ok(plant);
    }

    // 3-3. HttpPOST 작업
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    public ActionResult<PlantDTO> CreatePlant([FromBody] PlantDTO plantDTO)
    {

        // 추가
        Plant model = new()
        {
            Details = plantDTO.Details,
            Id = plantDTO.Id,
            ImageUrl = plantDTO.ImageUrl,
            Name = plantDTO.Name,
            Occupancy = plantDTO.Occupancy,
            Rate = plantDTO.Rate,
            Size = plantDTO.Size
        };
        _db.Plants.Add(model);
        _db.SaveChanges();

        return CreatedAtRoute("GetPlant", new { id = plantDTO.Id }, plantDTO);
    }

    //3-7. Http Delete 작업
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [HttpDelete("{id:int}", Name = "DeletePlant")]
    public IActionResult DeletePlant(int id)
    {

        // 삭제
        var plant = _db.Plants.FirstOrDefault(u => u.Id == id);
        if (plant == null)
        {
            return NotFound();
        }
        _db.Plants.Remove(plant);
        return NoContent();
    }

    [HttpPut("{id:int}", Name = "UpdatePlant")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public IActionResult UpdatePlant(int id, [FromBody] PlantDTO plantDTO)
    {

        // 업데이트 
        Plant model = new()
        {
            Details = plantDTO.Details,
            Id = plantDTO.Id,
            ImageUrl = plantDTO.ImageUrl,
            Name = plantDTO.Name,
            Occupancy = plantDTO.Occupancy,
            Rate = plantDTO.Rate,
            Size = plantDTO.Size
        };
        _db.Plants.Update(model);
        _db.SaveChanges();

        return NoContent();
    }
}

프로젝트 리소스

https://github.com/kimdaewoong2022/MorePlants_WebAPI/tree/d477fba7b771748d4a9d6eae0415bbaa6330b1bf