지난 포스팅에서는 LINQ를 활용해 데이터베이스에 속성을 추가하고 데이터를 조작하는 방법을 알아보았습니다.
이번 글에서는 Entity Framework의 1:1 관계 매핑을 살펴보고,
이를 구현하기 위한 DbContext 의 주요 메서드(OnConfiguring, OnModelCreating)와 Fluent API에 대해 알아보겠습니다.
1. 관계 매핑이란?
데이터베이스는 테이블 간의 관계를 통해 데이터를 관리합니다.
Entity Framework는 이를 Fluent API 또는 데이터 주석(Data Annotations)을 사용해 코드에서 정의할 수 있도록 지원합니다.
관계의 종류
1:1 관계 (One-to-One)
- 한 엔티티가 다른 하나의 엔티티와만 연결됩니다.
- 예: 제품 ↔ 제품 상세내용
1:N 관계 (One-to-Many)
- 한 엔티티가 여러 엔티티와 연결됩니다.
- 예: 카테고리 ↔ 제품
N:N 관계 (Many-to-Many)
-여러 엔티티가 다른 여러 엔티티와 연결됩니다.
- 예: 학생 ↔ 강의
출처 입력
이번 글에서는 1:1 관계에 초점을 맞추고, 1:N 관계와 N:N 관계는 이후 포스팅에서 다룰 예정입니다.
2. Fluent API
2.1 Fluent API란?
Fluent API는 Entity Framework에서 모델과 데이터베이스 간의 매핑 규칙을 정의하는 코드 방식입니다.
OnModelCreating 메서드 내에서 ModelBuilder 객체를 통해 설정되며,
관계 매핑 외에도 속성의 제약 조건, 기본값, 인덱스 등을 설정할 수 있습니다.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>() // Product 엔티티
.Property(p => p.Name) // Name 속성
.IsRequired() // 필수로 설정
.HasMaxLength(100); // 최대 길이 100으로 설정
}
장점으로는 데이터 주석으로 설정할 수 없는 세부 사항을 정의가 가능하며,
메서드 체인으로 직관적인 코드가 작성이 가능하다는 점이 있습니다.
3. DbContext 메서드
3.1 OnConfiguring
OnConfiguring 메서드는 DbContext가 데이터베이스와 연결하는 방식을 설정하는 곳입니다.
주로 연결 문자열(Connection String)을 정의하거나, 데이터베이스 제공자를 지정하는 데 사용됩니다.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=EFCoreDemoDb;Trusted_Connection=True;");
}
optionsBuilder.UseSqlServer(...)
- SQL Server 데이터베이스와 연결을 설정합니다.
연결 문자열(Connection String)
- 데이터베이스 위치와 인증 정보를 포함하며, DbContext가 해당 데이터베이스에 연결할 수 있도록 해줍니다
Tip
연결 문자열은 일반적으로 appsettings.json 파일에 저장하고, ConfigurationManager를 사용해 로드하는 것이 좋습니다. 이렇게 하면 보안과 유지보수가 용이해집니다.
출처 입력
3.2 OnModelCreating
OnModelCreating 메서드는 데이터베이스 테이블과 모델 클래스 간의 매핑 규칙을 설정하는 메서드입니다.
주로 Fluent API를 사용하여 관계, 제약 조건, 기본값 등을 설정합니다.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(p => p.Name)
.IsRequired() // Name은 필수 값
.HasMaxLength(100); // 최대 길이는 100자
}
Entity<T>():특정 엔티티(Product)를 지정합니다.
Property():속성을 설정합니다.
IsRequired():해당 속성을 필수로 지정합니다.
HasMaxLength():문자열 속성의 최대 길이를 지정합니다.
3. 1:1 관계 매핑
3.1 시나리오 설명
제품(Product): 독립적으로 존재 가능.
예: "Laptop"이라는 제품은 이름만으로도 유효.
제품 상세정보(ProductDetail): 제품에 종속적.
예: "Laptop"의 가격(Price)과 설명(Description)을 관리.
논리적 관계
제품은 상세정보를 가질 수도, 가지지 않을 수도 있지만, 상세정보는 반드시 제품에 연결되어야 합니다.
출처 입력
3.1 모델 작성 및 수정
ProductDetail 엔티티 생성
namespace EFCoreDemo.Model
{
public class ProductDetail
{
public int Id { get; set; }
public int Price { get; set; }
public string Description { get; set; } = string.Empty;
public Product? Product { get; set; }
}
}
Product 엔티티 수정
namespace EFCoreDemo.Model;
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public ProductDetail Detail { get; set; } = default!;
}
3.3 관계 매핑 코드
OnModelCreating 메서드에 1:1 관계 매핑을 추가합니다.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.HasOne(p => p.Detail) // Product는 하나의 Detail을 가짐
.WithOne(d => d.Product) // Detail도 하나의 Product를 가짐
.HasForeignKey<ProductDetail>(d => d.Id); // 외래 키를 ProductDetail.Id로 설정
}
4. 관계 매핑 적용 후 마이그레이션
4.1 DbContext 업데이트
DbSet을 추가하여 ProductDetail을 관리합니다.
public DbSet<ProductDetail> ProductDetails { get; set; } = default!;
4.2 마이그레이션 생성 및 적용
dotnet ef migrations add AddProductDetailRelation
dotnet ef database update
이렇게 ProductDetail 테이블이 생성되고 외래 키로 Product.Id를 참조합니다.
5. 마치며
1:1 관계 매핑은 독립적으로 존재하는 엔티티와 해당 엔티티에 종속적인 엔티티 간의 관계를 정의하는 데 사용됩니다.
이 글에서는 제품(Product)과 제품 상세정보(ProductDetail)를 예제로 다뤘습니다.
다음 포스팅에서는 1:N 관계 매핑을 학습하며, 제품과 카테고리 간의 관계를 매핑하는 방법을 알아보겠습니다.
'Entity Framework' 카테고리의 다른 글
C# 닷넷 엔티티 프레임워크(Entity Framework) N:N 관계 매핑 (0) | 2025.01.22 |
---|---|
엔티티 프레임워크(Entity Framework) 1:N 관계 매핑 (0) | 2025.01.22 |
EF 데이터베이스 구조 변경 및 마이그레이션 심화 (0) | 2025.01.18 |
Entity Framework를 활용한 CRUD 작업 (0) | 2025.01.15 |
LINQ로 간편하게 데이터 조회하기 (0) | 2025.01.15 |