Entity Framework

LINQ로 간편하게 데이터 조회하기

zorimo 2025. 1. 15. 00:36

지난 포스팅에서는 Code-First 방식으로 Entity Framework를 설정하고, 기본적인 환경을 구축하는 방법을 배웠습니다.

이번 글에서는 LINQ를 사용해 데이터베이스에서 데이터를 조회하는 방법을 간단한 예제와 함께 알아보겠습니다.


1. LINQ란 무엇인가?

 

https://learn.microsoft.com/ko-kr/dotnet/csharp/linq/

LINQ(Language Integrated Query) C#에서 제공하는 데이터 쿼리 도구로,

SQL을 직접 작성하지 않고도 객체 지향 프로그래밍 언어의 문법으로 데이터를 조회하고 조작할 수 있습니다.

SQL 대신 LINQ를 사용하면 코드와 데이터 간의 일관성을 유지할 수 있어 개발 생산성을 크게 높일 수 있습니다.


2. 데이터 준비하기

LINQ를 실습하기 위해 데이터베이스에 데이터를 미리 준비해야 합니다.

Main 메서드에 아래 코드를 추가해 데이터를 초기화합니다.

using EFCoreDemo;
using EFCoreDemo.Model;

class Program
{
    static void Main()
    {
        SeedDatabase();
    }

    static void SeedDatabase()
    {
        using var context = new EFCoreDemoDbContext();
        if (!context.Products.Any())
        {
            context.Products.AddRange(
                new Product { Name = "Laptop", Price = 1500 },
                new Product { Name = "Tablet", Price = 800 },
                new Product { Name = "Smartphone", Price = 1200 }
            );
            context.SaveChanges();
            Console.WriteLine("데이터가 성공적으로 추가되었습니다.");
        }
        else
        {
            Console.WriteLine("이미 데이터가 존재합니다.");
        }
    }
}
 

2.1 SeedDatabase

위 코드에서 SeedDatabase 메서드는 Products 테이블에 데이터가 없을 경우,

샘플 데이터를 추가하는 역할을 합니다.

 

코드 동작 원리는 다음과 같습니다.


2.1.1 데이터베이스 연결 및 상태 확인

using var context = new EFCoreDemoDbContext();
 

데이터베이스와의 연결을 생성합니다. 이 연결을 통해 테이블 상태를 확인하고 데이터를 조작할 수 있습니다.

if (!context.Products.Any())
 

Products 테이블에 데이터가 있는지 확인합니다. 데이터가 없으면 아래의 데이터 추가 작업이 실행됩니다.


2.1.2 샘플 데이터 추가

context.Products.AddRange()
 

세 가지 Product 엔티티를 한꺼번에 테이블에 추가합니다. (Name: 제품 이름, Price: 제품 가격)

context.SaveChanges();
 

변경된 내용을 데이터베이스에 저장합니다. 실제 쿼리가 실행되는 단계입니다.


2.1.3 결과 메세지 출력

데이터가 성공적으로 추가된 경우 "데이터가 성공적으로 추가되었습니다."라는 메시지를 출력합니다.

이미 데이터가 존재하는 경우 추가 작업을 생략하고 "이미 데이터가 존재합니다."라는 메시지를 출력합니다.


2.1.4 참고

Main 메서드 실행 후 SeedDatabase 호출을 멈추면 추가 데이터는 더 이상 삽입되지 않습니다.

하지만, 메서드를 다시 실행하는 상황을 대비해 데이터가 이미 존재할 경우 추가 작업을 건너뛰도록 설계했습니다.


3. LINQ로 데이터 조회

데이터베이스에서 데이터를 조회할 때 LINQ는 여러 메서드를 제공합니다.

 

이번 포스팅에서는 데이터를 조회할 때 자주 사용하는

ToList, Where, Select, OrderBy, OrderByDescending 메서드의 기본적인 사용법을 살펴보겠습니다.


3.1 모든 데이터 조회하기

테이블에 저장된 모든 데이터를 조회하기 위해 ToList 메서드를 사용합니다.

ToList는 데이터베이스에 쿼리를 실행하고, 그 결과를 메모리에 로드하여 리스트(List) 형태로 반환합니다.

다만 대량의 데이터가 있으면 메모리에 부담이 될 수 있으므로 필요한 데이터만 필터링하여 사용하는 것을 권장합니다.

 

Main에 다음과 같이 추가해주세요.

static void Main()
{
    SeedDatabase();

    using var context = new EFCoreDemoDbContext();
    var products = context.Products.ToList();

    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 조건에 맞는 데이터 조회하기

특정 조건을 만족하는 데이터를 조회하기 위해서 Where 메서드를 사용합니다.

 

Where는 LINQ에서 조건을 지정해 데이터를 필터링하는 메서드입니다.

조건에 맞는 데이터만 반환하며, SQL의 WHERE 절과 동일한 역할을 합니다.

조건이 많아지면 읽기 쉽도록 주석으로 설명을 추가하시는게 좋습니다.

 

Main을 다음과 같이 수정해주세요.

static void Main()
{
    SeedDatabase();

    using var context = new EFCoreDemoDbContext();

    // 가격이 1000 이상인 제품만 필터링
    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.3 특정 열만 선택하기

데이터의 특정 열만 가져오기 위해 Select 메서드를 사용합니다.

 

Select는 LINQ에서 지정한 열(또는 속성)만 추출하는 메서드입니다.

객체 전체가 아닌 필요한 속성만 선택할 때 사용하며, SQL의 SELECT 절과 유사합니다.

 

Main을 다음과 같이 수정해주세요.

static void Main()
{
    SeedDatabase();

    using var context = new EFCoreDemoDbContext();
    var productNames = context.Products
                          .Select(p => p.Name)
                          .ToList();

    Console.WriteLine("제품 이름 목록");
    foreach (var name in productNames)
    {
        Console.WriteLine($"Name: {name}");
    }
}
 

결과

제품 이름 목록
Product Name: Laptop
Product Name: Tablet
Product Name: Smartphone
 

3.4 데이터 정렬하기

데이터를 정렬하려면 OrderBy 또는 OrderByDescending 메서드를 사용합니다.

 

OrderBy는 데이터를 오름차순(Ascending Order)으로 정렬하는 메서드입니다.

가격이 낮은 순으로 정렬하거나 이름의 알파벳 순서로 정렬할 때 사용하며 SQL의 ORDERBY 절과 유사합니다.

 

OrderByDesending은 데이터를 내림차순(Descending Order)으로 정렬하는 메서드입니다.

가격이 높은 순으로 정렬하거나 최신 데이터 순으로 정렬할 때 사용합니다.

 

Main을 다음과 같이 수정해주세요.

static void Main()
{
    SeedDatabase();

    using var context = new EFCoreDemoDbContext();
    var sortedProducts = context.Products
                              .OrderBy(p => p.Price)
                              .ToList();

    Console.WriteLine("가격 순으로 정렬된 제품목록");
    foreach (var product in sortedProducts)
    {
        Console.WriteLine($"Name: {product.Name}, Price: {product.Price}");
    }
}
 

결과

가격 순으로 정렬된 제품목록
Name: Tablet, Price: 800
Name: Smartphone, Price: 1200
Name: Laptop, Price: 1500
 

4. LINQ와 SQL 비교

LINQ는 SQL의 역할을 객체 지향적인 방식으로 간결하게 표현합니다.

예를 들어, LINQ에서 작성한 쿼리는 Entity Framework가 SQL로 변환하여 데이터베이스에서 실행합니다.

아래 코드를 보면 LINQ와 SQL이 수행하는 역할이 동일하지만 문법이 다르다는 점을 알 수 있습니다.

 

예를들어 LINQ로 가격이 1000 이상인 제품 조회하는 방법은 다음과 같습니다.

var expensiveProducts = context.Products
                               .Where(p => p.Price >= 1000)
                               .ToList();
 

위 코드는 프로그래밍 언어에서 객체로 데이터를 조회하는 방식으로 작성되며,

Entity Framework는 이 LINQ 코드를 데이터베이스에 필요한 SQL 쿼리로 변환하여 실행합니다.

 

실제로 실행되는 SQL은 다음과 같습니다.

SELECT * FROM Products WHERE Price >= 1000;
 

5. 마치며

LINQ는 데이터베이스와 객체 간의 간극을 줄이고, 데이터를 간단하고 직관적으로 조회할 수 있도록 도와줍니다.

이번 포스팅에서는 LINQ의 ToList, Where, Select, OrderBy 메서드를 다루며 기본적인 데이터 조회와 필터링 방법을 알아보았습니다.

 

다음 포스팅에서는 LINQ를 사용해 데이터를 삽입, 수정, 삭제하는 방법을 예제와 함께 알아보겠습니다.