이 섹션에서는 앞서 정의한 IPlantRepository
인터페이스를 구현하는 과정을 배웁니다.
Repository 패턴을 사용하여 데이터 액세스 로직을 캡슐화하고, 애플리케이션의 나머지 부분과 데이터베이스 간의 결합도를 낮춥니다.
- CRUD 메서드 구현:
Create
: 비동기적으로 Plant 객체를 데이터베이스에 추가하고 변경 사항을 저장합니다.Remove
: 주어진 Plant 객체를 데이터베이스에서 삭제하고 변경 사항을 저장합니다.Save
: 비동기적으로 모든 변경 사항을 데이터베이스에 저장합니다.GetAll
: 주어진 조건에 따라 모든 Plant 객체를 검색하거나, 조건이 없으면 모든 객체를 검색합니다. 필터링은 LINQ 표현식을 사용하여 수행됩니다.Get
: 주어진 조건에 따라 단일 Plant 객체를 검색합니다.tracked
매개변수를 사용하여 Entity Framework Core의 추적 기능을 활성화하거나 비활성화할 수 있습니다.
- 조건부 필터링 및 추적 제어:
GetAll
과Get
메서드에서는 LINQ 표현식을 사용하여 동적으로 데이터를 필터링할 수 있습니다. 또한,AsNoTracking
메서드를 사용하여 필요에 따라 데이터 추적을 비활성화할 수 있습니다. - 비동기 프로그래밍: 모든 데이터 액세스 메서드는 비동기적으로 구현되어 있어, 데이터베이스 작업 중에 애플리케이션의 응답성을 유지할 수 있습니다.
- Repository 등록:
Program.cs
파일에서IPlantRepository
인터페이스와 그 구현체인PlantRepository
클래스를 서비스 컨테이너에 등록합니다. 이를 통해 API 컨트롤러에서IPlantRepository
를 주입받아 사용할 수 있게 됩니다. - Plant API 컨트롤러 수정:
ApplicationDbContext
대신IPlantRepository
를 주입받아 사용합니다.CRUD 작업을 위해 Repository의 메서드(CreateAsync
,GetAsync
,GetAllAsync
,UpdateAsync
,RemoveAsync
)를 호출합니다.비동기 메서드를 사용하여 데이터베이스 작업을 처리합니다. 이는 애플리케이션의 응답성을 향상시키고, 리소스 사용을 최적화합니다.
- 비동기 메서드 적용: 모든 데이터베이스 작업을 비동기적으로 수행합니다.
await
키워드를 사용하여 비동기 작업을 기다리고, 메서드 시그니처에async
와Task
를 추가하여 비동기 메서드로 변환합니다.Comment - 조건부 데이터 검색:
GetAsync
와GetAllAsync
메서드에서는 LINQ 표현식을 사용하여 동적으로 데이터를 필터링합니다. 이를 통해 유연하게 데이터를 조회할 수 있습니다. - 추적 제어:
GetAsync
메서드에서tracked
매개변수를 사용하여 Entity Framework Core의 변경 추적 기능을 제어합니다. 필요에 따라 데이터 조회 시 변경 추적을 비활성화하여 성능을 최적화할 수 있습니다.Comment - 테스트 및 검증: 수정된 API 컨트롤러의 모든 CRUD 작업을 테스트하여 Repository 패턴의 적용이 정상적으로 이루어졌는지 확인합니다.
// PlantRepository.cs
public class PlantRepository : IPlantRepository
{
private readonly ApplicationDbContext _db;
public PlantRepository(ApplicationDbContext db)
{
_db = db;
}
public async Task Create(Plant entity)
{
await _db.Plants.AddAsync(entity);
await Save();
}
public async Task<Plant> Get(Expression<Func<Plant, bool>> filter = null, bool tracked = true)
{
IQueryable<Plant> query = _db.Plants;
if (!tracked)
{
query = query.AsNoTracking();
}
if (filter != null)
{
query = query.Where(filter);
}
return await query.FirstOrDefaultAsync();
}
public async Task<List<Plant>> GetAll(Expression<Func<Plant, bool>> filter = null)
{
IQueryable<Plant> query = _db.Plants;
if (filter != null)
{
query = query.Where(filter);
}
return await query.ToListAsync();
}
public async Task Remove(Plant entity)
{
_db.Plants.Remove(entity);
await Save();
}
public async Task Save()
{
await _db.SaveChangesAsync();
}
}
// Program.cs
builder.Services.AddScoped<IPlantRepository, PlantRepository>();
Repository 패턴의 적용은 애플리케이션의 데이터 액세스 로직을 추상화하고, 컨트롤러와 데이터베이스 간의 결합도를 낮추어 애플리케이션의 아키텍처를 개선합니다. 비동기 프로그래밍 모델을 사용함으로써 데이터베이스 작업의 효율성과 애플리케이션의 응답성을 더욱 향상시킬 수 있습니다.