반응형
EF Core에서 N(Many-to-Many) 관계 매핑
Entity Framework Core (EF Core)는 객체-관계형 매퍼(ORM)로, 데이터베이스와 객체 지향 프로그래밍을 연결하는 데 도움을 줍니다. EF Core 5.0 이상 버전에서는 Many-to-Many (N) 관계를 보다 간편하게 설정할 수 있습니다. 이 글에서는 최신 EF Core를 사용하여 Many-to-Many 관계를 설정하고, 이를 활용하는 방법을 설명합니다.
1. Many-to-Many 관계 개요
Many-to-Many 관계는 두 엔티티가 서로 여러 관계를 가질 수 있는 경우를 의미합니다. 예를 들어, 학생(Student)은 여러 과목(Course)을 수강할 수 있고, 과목도 여러 학생이 수강할 수 있습니다.
2. 모델 클래스 정의
EF Core 5.0 이상에서는 중간 엔티티를 명시적으로 정의하지 않고도 Many-to-Many 관계를 설정할 수 있습니다. 이를 위해 학생(Student)과 과목(Course) 클래스는 다음과 같이 정의됩니다.
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public ICollection<Course> Courses { get; set; }
}
public class Course
{
public int CourseId { get; set; }
public string Title { get; set; }
public ICollection<Student> Students { get; set; }
}
3. DbContext 설정
DbContext에서 OnModelCreating 메서드를 통해 Many-to-Many 관계를 설정합니다.
public class SchoolContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasMany(s => s.Courses)
.WithMany(c => c.Students)
.UsingEntity<Dictionary<string, object>>(
"StudentCourse",
j => j.HasOne<Course>().WithMany().HasForeignKey("CourseId"),
j => j.HasOne<Student>().WithMany().HasForeignKey("StudentId"));
}
}
4. 데이터 추가 및 조회
4-1 데이터 추가
기존의 Course 엔티티가 이미 존재하는 경우, 새로운 Student를 생성하고 기존 Course와 연관시킬 수 있습니다.
using (var context = new SchoolContext())
{
// 데이터베이스에서 기존 Course를 검색
var existingCourse = context.Courses.FirstOrDefault(c => c.Title == "Mathematics");
if (existingCourse != null)
{
// 새로운 Student 생성
var student = new Student { Name = "Jane Doe" };
// 기존 Course와 연관
student.Courses = new List<Course> { existingCourse };
// Student 추가
context.Students.Add(student);
// 변경사항 저장
context.SaveChanges();
}
}
4-2 데이터 조회
학생과 관련된 과목 정보를 함께 조회하려면 Include 메서드를 사용합니다.
using (var context = new SchoolContext())
{
var students = context.Students
.Include(s => s.Courses)
.ToList();
foreach (var student in students)
{
Console.WriteLine($"{student.Name} is enrolled in the following courses:");
foreach (var course in student.Courses)
{
Console.WriteLine(course.Title);
}
}
}
5. 학생 엔티티 업데이트 (과목 추가 및 수정)
과목 추가
if (student != null)
{
// 새로운 과목 생성
var newCourse = new Course { Title = "Physics" };
// 학생의 과목 목록에 추가
student.Courses.Add(newCourse);
// 변경사항 저장
context.SaveChanges();
}
과목 수정
if (student != null)
{
// 학생의 첫 번째 과목을 수정 (예제)
var course = student.Courses.FirstOrDefault();
if (course != null)
{
course.Title = "Advanced Mathematics";
}
// 변경사항 저장
context.SaveChanges();
}
과목 제거
if (student != null)
{
// 첫 번째 과목을 제거 (예제)
var courseToRemove = student.Courses.FirstOrDefault();
if (courseToRemove != null)
{
student.Courses.Remove(courseToRemove);
}
// 변경사항 저장
context.SaveChanges();
}
6. 예외 처리 및 개선
데이터베이스 작업 중 발생할 수 있는 오류를 처리하기 위해 예외 처리를 추가할 수 있습니다.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public ICollection<Course> Courses { get; set; }
}
public class Course
{
public int CourseId { get; set; }
public string Title { get; set; }
public ICollection<Student> Students { get; set; }
}
public class SchoolContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasMany(s => s.Courses)
.WithMany(c => c.Students)
.UsingEntity<Dictionary<string, object>>(
"StudentCourse",
j => j.HasOne<Course>().WithMany().HasForeignKey("CourseId"),
j => j.HasOne<Student>().WithMany().HasForeignKey("StudentId"));
}
}
public class Program
{
public static void Main()
{
using (var context = new SchoolContext())
{
try
{
// 데이터베이스에서 기존 Course를 검색
var existingCourse = context.Courses.FirstOrDefault(c => c.Title == "Mathematics");
if (existingCourse != null)
{
// 새로운 Student 생성
var student = new Student { Name = "Jane Doe" };
// 기존 Course와 연관
student.Courses = new List<Course> { existingCourse };
// Student 추가
context.Students.Add(student);
// 변경사항 저장
context.SaveChanges();
}
else
{
Console.WriteLine("Course not found.");
}
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
}
반응형
'C#' 카테고리의 다른 글
.NET Core Model 유효성 검사 응답 처리 방법 (0) | 2024.08.26 |
---|---|
C#에서 동기메서드를 비동기 방식으로 처리하는 방법 (0) | 2024.08.22 |
C# 비동기 프로그래밍: 비동기 vs 동기 처리 (0) | 2024.07.10 |
.NET Framework 4.5.2 다운로드 (0) | 2024.05.13 |
.NET Framework 삭제 방법 (0) | 2024.05.13 |