EF Core?
EF Core는 Entity Framework의 경량화된 버전으로, .NET Core 및 .NET 5 이상에서 사용할 수 있다. 데이터베이스와의 상호 작용을 단순화하고 개발자가 데이터베이스에 대한 쿼리 및 조작을 수행할 수 있는 ORM(Object-Relational Mapping) 도구이다.
주요 기능
- 데이터베이스에 대한 CRUD(Create, Read, Update, Delete) 작업을 지원한다.
- LINQ(Language Integrated Query)를 사용하여 데이터베이스 쿼리를 작성할 수 있다.
- 데이터베이스 스키마를 코드로 정의할 수 있는 Code First 접근 방식을 제공한다.
- 다양한 데이터베이스 시스템과 호환된다.
EF Core의 장점
- 개발자가 데이터베이스와의 상호 작용을 쉽게 할 수 있다.
- 데이터베이스에 대한 추상화 계층을 제공하여 유지 보수 및 확장성을 향상시킨다.
- 다양한 데이터베이스 시스템과의 호환성을 제공한다.
- LINQ를 사용하여 간편하게 데이터베이스 쿼리를 작성할 수 있다.
EF Core의 한계
- EF Core는 아직 모든 Entity Framework의 기능을 지원하지 않을 수 있다.
- 일부 고급 데이터베이스 기능에 대한 지원이 제한적일 수 있다.
- 성능 측면에서 일부 상황에서는 원시 SQL 쿼리를 작성하는 것이 더 효율적일 수 있다.
EF Core 사용 방법
- 프로젝트에 EF Core NuGet 패키지를 추가한다.
- DbContext 클래스를 작성하고 데이터베이스 연결 정보를 설정한다.
- 모델 클래스를 작성하고 데이터베이스 테이블과 매핑한다.
- LINQ를 사용하여 데이터베이스 쿼리를 작성하고 실행한다.
- 변경 내용을 데이터베이스에 저장하거나 업데이트한다.
Entity Framework Core 사용을 위한 데이터베이스 설치
- SQL Server 설치
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
- 테스트를 위한 InMemory 설치
dotnet add package Microsoft.EntityFrameworkCore.InMemory
DbContext 서브 클래스 작성
public class CatalogContext : DbContext
{
public CatalogContext(DbContextOptions<CatalogContext> options) : base(options)
{
}
public DbSet<CatalogItem> CatalogItems { get; set; }
public DbSet<CatalogBrand> CatalogBrands { get; set; }
public DbSet<CatalogType> CatalogTypes { get; set; }
}
EF Core 구성 (데이터베이스 연결 정보 설정)
- SQL Server 사용시
builder.Services.AddDbContext<CatalogContext>( options => options.UseSqlServer( builder.Configuration.GetConnectionString("DefaultConnection")));
- InMemory 사용시
builder.Services.AddDbContext<CatalogContext>(options => options.UseInMemoryDatabase());
데이터 가져오기
var brandItems = await _context.CatalogBrands
.Where(b => b.Enabled)
.OrderBy(b => b.Name)
.Select(b => new SelectListItem {
Value = b.Id, Text = b.Name })
.ToListAsync();
- 이름순 정렬, Enabled 속성으로 필터링, SelectListItem형식의 CatalogBrands를 조회
- 즉각 실행하기 위해
.ToListAsync()
를 호출을 추가하는 것이 중요하다.
데이터 저장
// 데이터 추가 Create
var newBrand = new CatalogBrand() { Brand = "Acme" };
_context.Add(newBrand);
await _context.SaveChangesAsync();
// 데이터 수정 read and update
var existingBrand = _context.CatalogBrands.Find(1);
existingBrand.Brand = "Updated Brand";
await _context.SaveChangesAsync();
// 데이터 삭제 read and delete (alternate Find syntax)
var brandToDelete = _context.Find<CatalogBrand>(2);
_context.CatalogBrands.Remove(brandToDelete);
await _context.SaveChangesAsync();
- EF Core느 엔터티를 가져오고 저장하기 위한 동기/비동기 메서드를 모두 지원한다.
- 웹 어플리케이션에서 데이터 액세스 작업을 기다리는 동안 웹서버 스레드가 차단되지 않도록 하깅 위해 비동기 메서드에 async/await 패턴을 사용하는 것이 좋다.
관련 데이터 가져오기
- EF Core는 엔터티를 가져올 때 데이터베이스에 직접 저장되어있는 모든 프로퍼티를 함께 가져온다.
- 관련 엔터티 목록들과 같은 Navigation 속성은
null
값으로 입력되는 경우가 있다. - 이 프로세스는 EF Core가 데이터를 필요 이상으로 가져오지 않게하므로, 요청을 신속하고 효율적인 방식으로 처리하고 응답을 반환해야하는 웹 어플리케이션에선 매우 중요하다.
- 즉시 로드
eager loading
을 사용하여 엔터티와의 관계를 포함하려면 다음과 같이 쿼리에Include
메서드를 사용하여 속성을 지정할 수 있다.
// .Include 를 사용하려면 using Microsoft.EntityFrameworkCore 을 추가해야한다.
var brandsWithItems = await _context.CatalogBrands
.Include(b => b.Items)
.ToListAsync();
- 여러 관계를 포함할 수 있고,
ThenInclude
를 사용하여 하위 관계를 포함할 수도 있다. - 마침표로 구분된 문자열을
.Include()
메서드에 전달해서 Navigation 속성을 추가하는 방법도 있다. .Include("Items.Products")
specification
은 필터링 논리를 캡슐화할 수 있을 뿐만 아니라 어떤 프로퍼티를 읽어올지를 포함해 반환 데이터의 형태를 지정할 수 있다.// 모든 표현식 기반 Include query = specification.Includes.Aggregate(query, (current, include) => current.Include(include)); // 문자열 기반 Include query = specification.IncludeStrings.Aggregate(query, (current, include) => current.Include(include));
- 또 다른 방법으로는 명시적 로드
explict loading
이 있다. 이미 읽어온 엔터티에 추가 데이터를 가져올 수 있지만, DB 왕복 횟수를 최소화해야하는 웹 어플리케이션에서는 사용하지 않는 것이 좋다. - 기본적으로 사용하지 않도록 설정되어 있으며
Microsoft.EntityFrameworkCore.Proxies
를 설치해야한다.
반응형
'Backend > C# .NET' 카테고리의 다른 글
C#의 recode 레코드 왜 쓰나요? 샘플 코드 예제 / 명명 규칙 (0) | 2023.12.04 |
---|---|
CQRS 패턴을 적용한 MediatR과 FluentValidation (0) | 2023.11.28 |
[C#] JWS 생성 (JSON Web Signature) / 검증 / RS256 (0) | 2023.08.08 |
[ASP.NET] Entity Framework Core (0) | 2021.12.13 |
[ASP.NET] 개요 / MVC 패턴 / 의존성 주입 패턴 (0) | 2021.12.07 |