Entity Framework

Entity Framework를 활용한 CRUD 작업

zorimo 2025. 1. 15. 20:00

 

지난 포스팅에서는 LINQ를 사용해 데이터를 조회하는 방법을 알아보았습니다.

이번 글에서는 Entity Framework를 활용한 CRUD 작업(Create, Read, Update, Delete)을 살펴보겠습니다.

 

CRUD는 데이터베이스를 다루는 기본 작업이며,

이를 통해 데이터를 생성, 조회, 수정, 삭제하는 과정을 이해할 수 있습니다.


1. CRUD란?

CRUD는 다음과 같은 작업의 약자입니다.

Create: 데이터를 생성.
Read: 데이터를 조회.
Update: 데이터를 수정.
Delete: 데이터를 삭제.

Entity Framework에서는 DbContextLINQ를 활용해 이러한 작업을 간단히 구현할 수 있습니다.

모든 작업이 끝나면 SaveChanges()를 호출하여 변경 내용을 데이터베이스에 반영합니다.


2. SaveChanges란?

 

SaveChanges는 CRUD 작업의 중심이 되는 메서드입니다.

모든 추가(Add), 수정(Update), 삭제(Delete) 작업은 메모리에서만 이루어지며,

SaveChanges를 호출해야만 실제 데이터베이스에 반영됩니다.

기억하고 계신가요?
지난 포스팅에서 SaveChanges는 변경된 내용을 데이터베이스에 저장하고,
실제 쿼리가 실행되는 단계라고 설명드렸습니다.

 

예를 들어, 다음과 같은 작업에서 SaveChanges는 반드시 호출되어야 합니다

 

var newProduct = new Product { Name = "Tablet", Price = 800 };
context.Products.Add(newProduct); // 메모리에 데이터 추가
context.SaveChanges();            // 데이터베이스에 반영
 

SaveChanges를 호출하지 않으면 변경된 내용은 메모리에만 남고 데이터베이스에는 적용되지 않습니다.

 

이 점을 꼭 기억하세요.

마치 문서를 열심히 작성하고 저장 버튼을 누르지 않은 것과 같은 상황이 벌어질 수 있습니다.


3. CRUD 작업 구현

3.1 Create (데이터 생성)

데이터를 생성하려면 Add 또는 AddRange 메서드를 사용합니다.

SeedDatabase 메서드 아래에 다음 코드를 추가합니다.

static void CreateProduct()
{
    using var context = new EFCoreDemoDbContext();

    var newProduct = new Product { Name = "Headphones", Price = 200 };
    context.Products.Add(newProduct); // 새로운 데이터 추가
    context.SaveChanges(); // 변경 내용을 데이터베이스에 저장

    Console.WriteLine("새 제품이 성공적으로 추가되었습니다.");
}
 

3.2 Read (데이터 조회)

LINQ를 사용하면 데이터를 다양하게 조회할 수 있습니다.

이전 포스팅에서도 직접 구현해보았지만 다시 한 번 다뤄보도록 하겠습니다.

또한 여기에서는 자주 사용하는 몇 가지 메서드를 설명하겠습니다.

 

3.2.1 모든 데이터 조회 (ToList)

ToList 메서드는 테이블의 모든 데이터를 리스트(List) 형태로 가져옵니다.

데이터베이스에 SELECT * FROM [테이블] 쿼리를 실행한 것과 동일한 역할을 합니다.

static void ReadAllProducts()
{
    using var context = new EFCoreDemoDbContext();

    var products = context.Products.ToList(); // 모든 데이터 조회
    Console.WriteLine("제품 목록");
    foreach (var product in products)
    {
        Console.WriteLine($"Name: {product.Name}, Price: {product.Price}");
    }
}
 

결과

제품 목록
Name: Laptop, Price: 1500
Name: Tablet, Price: 800
Name: Smartphone, Price: 1200
 

3.2.2 첫 번째 데이터 조회 (First)

First 메서드는 조건에 맞는 첫 번째 데이터를 반환합니다.

조건에 맞는 데이터가 없을 경우 예외를 발생시키니 주의가 필요합니다.

static void ReadFirstProduct()
{
    using var context = new EFCoreDemoDbContext();

    var firstProduct = context.Products.First(p => p.Price > 1000); // 조건에 맞는 첫 번째 데이터 조회
    Console.WriteLine($"첫 번째 제품: {firstProduct.Name}, Price: {firstProduct.Price}");
}
 

결과

첫 번째 제품: Laptop, Price: 1500
 

3.2.3 첫 번째 데이터 조회 (FirstOrDefault)

FirstOrDefault 메서드는 조건에 맞는 첫 번째 데이터를 반환하며,

조건에 맞는 데이터가 없을 경우 null을 반환합니다. 예외가 발생하지 않기 때문에 안전하게 사용할 수 있습니다.

static void ReadFirstOrDefaultProduct()
{
    using var context = new EFCoreDemoDbContext();

    var product = context.Products.FirstOrDefault(p => p.Price > 2000); // 조건에 맞는 데이터가 없을 경우
    if (product == null)
    {
        Console.WriteLine("조건에 맞는 제품이 없습니다.");
    }
    else
    {
        Console.WriteLine($"첫 번째 제품: Name: {product.Name}, Price: {product.Price}");
    }
}
 

결과

조건에 맞는 제품이 없습니다.
 

3.2.4 조건에 맞는 데이터 조회 (Where)

Where 메서드는 조건에 맞는 데이터를 필터링합니다.

SQL의 WHERE절과 동일한 역할을 하며, 반환된 데이터는 여러 개일 수 있습니다.

static void ReadExpensiveProducts()
{
    using var context = new EFCoreDemoDbContext();

    var expensiveProducts = context.Products
                                   .Where(p => p.Price >= 1000) // 조건 필터링
                                   .ToList();

    Console.WriteLine("가격이 1000 이상인 제품 목록");
    foreach (var product in expensiveProducts)
    {
        Console.WriteLine($"Name: {product.Name}, Price: {product.Price}");
    }
}
 

결과

가격이 1000 이상인 제품목록
Name: Laptop, Price: 1500
Name: Smartphone, Price: 1200
 

3.2.5 요약

ToList: 모든 데이터를 리스트로 반환.

First: 조건에 맞는 첫 번째 데이터를 반환(조건이 없을 경우 예외 발생).

FirstOrDefault: 조건에 맞는 첫 번째 데이터를 반환하거나 데이터가 없으면 null 반환.

Where: 조건에 맞는 데이터를 필터링.

출처 입력

이처럼 다양한 LINQ 메서드를 사용해 데이터를 효율적으로 조회할 수 있습니다.


3.3 Update (데이터 수정)

데이터를 수정하려면 먼저 수정할 데이터를 조회한 후, 속성을 변경하고 SaveChanges를 호출합니다.

static void UpdateProduct()
{
    using var context = new EFCoreDemoDbContext();

    var product = context.Products.FirstOrDefault(p => p.Name == "Tablet"); // 수정할 데이터 조회
    if (product != null)
    {
        product.Price = 900; // 가격 수정
        context.SaveChanges(); // 변경 내용을 저장
        Console.WriteLine("제품 정보가 성공적으로 업데이트되었습니다.");
    }
    else
    {
        Console.WriteLine("해당 제품을 찾을 수 없습니다.");
    }
}
 

3.4 Delete (데이터 삭제)

데이터를 삭제하려면 Remove 또는 RemoveRange 메서드를 사용합니다.

static void DeleteProduct()
{
    using var context = new EFCoreDemoDbContext();

    var product = context.Products.FirstOrDefault(p => p.Name == "Smartphone"); // 삭제할 데이터 조회
    if (product != null)
    {
        context.Products.Remove(product); // 데이터 삭제
        context.SaveChanges(); // 변경 내용을 저장
        Console.WriteLine("제품이 성공적으로 삭제되었습니다.");
    }
    else
    {
        Console.WriteLine("해당 제품을 찾을 수 없습니다.");
    }
}

4. Main 메서드에서 CRUD 실행

위에서 작성한 메서드를 호출해 CRUD 작업을 실행합니다.

static void Main()
{
    // 데이터 준비
    SeedDatabase();

    // CRUD 작업 실행
    CreateProduct();
    ReadAllProducts(); // 또는, ReadFirstProduct, ReadFirstOrDefaultProduct, ReadExpensiveProducts
    UpdateProduct();
    DeleteProduct();
    ReadProducts();
}
 

결과

새 제품이 성공적으로 추가되었습니다.
제품 목록
Name: Laptop, Price: 1500
Name: Tablet, Price: 800
Name: Smartphone, Price: 1200
Name: Headphones, Price: 200
제품 정보가 성공적으로 업데이트되었습니다.
제품이 성공적으로 삭제되었습니다.
제품 목록
Name: Laptop, Price: 1500
Name: Tablet, Price: 900
Name: Headphones, Price: 200

5. 마치며

이번 포스팅에서는 Entity Framework를 활용한 CRUD 작업(Create, Read, Update, Delete)을 살펴보았습니다.

 

핵심 요약은 다음과 같습니다.

SaveChanges: 모든 변경 사항을 데이터베이스에 저장하는 필수 메서드.
Create: 데이터를 추가할 때는 Add 메서드 사용.
Read: 데이터를 조회할 때는 LINQ 메서드(ToList, Where, FirstOrDefault) 활용.
Update: 데이터를 수정 후 SaveChanges 호출.
Delete: 데이터를 삭제할 때는 Remove 메서드 사용.

 

다음 포스팅에서는 데이터베이스 구조 변경과 마이그레이션에 대해 알아보겠습니다.