본문 바로가기
프로그래밍/C#

[C#] LINQ (Language Integrated Query)

by 오 복 이 2024. 11. 18.

LINQ는 C# 코드에서 데이터 소스(SQL 데이터베이스, 컬렉션, XML 등)를 일관성 있게 쿼리할 수 있도록 해주는 도구입니다. 이 글에서는 LINQ의 소개와 필요성, LINQ를 사용한 데이터 질의, IEnumerable과 IQueryable 인터페이스를 다룹니다.

 


1. LINQ의 소개와 필요성

LINQ란 무엇인가?

LINQ는 Language Integrated Query의 약자로, C#에서 데이터 소스를 쿼리하는 기능을 제공합니다. LINQ는 다양한 데이터 소스에 대해 일관된 문법으로 데이터를 검색, 필터링, 변환할 수 있습니다. 대표적으로 다음과 같은 데이터 소스에서 사용됩니다:

  • 컬렉션 (예: List, Array)
  • 데이터베이스 (LINQ to SQL, Entity Framework)
  • XML 문서 (LINQ to XML)
  • 기타 데이터 소스 (예: 파일, Web API)

LINQ가 필요한 이유

  1. 일관된 쿼리 문법: LINQ는 SQL, 컬렉션, XML 등 서로 다른 데이터 소스에 대해 동일한 쿼리 문법을 제공합니다.
  2. 코드 가독성 향상: 데이터 처리 코드가 간결해지고 읽기 쉬워집니다.
  3. 타입 안전성: 컴파일 시점에 쿼리 오류를 잡아주기 때문에 런타임 오류를 줄일 수 있습니다.
  4. 유연한 데이터 변환: 데이터를 필터링하고 변환하는 작업을 간단히 수행할 수 있습니다.

2. LINQ를 사용한 데이터 질의

LINQ는 **쿼리 문법(Query Syntax)**과 메서드 문법(Method Syntax) 두 가지 스타일을 제공합니다. 둘 다 동일한 결과를 반환하며, 상황에 따라 편리한 방식을 사용할 수 있습니다.

데이터 준비

먼저, LINQ를 사용할 데이터 소스를 준비합니다.

 
using System;
using System.Collections.Generic;
using System.Linq; // LINQ를 사용하려면 필수

class Program
{
    static void Main()
    {
        // 예제 데이터: 학생 리스트
        List<Student> students = new List<Student>
        {
            new Student { Id = 1, Name = "홍길동", Score = 85 },
            new Student { Id = 2, Name = "김철수", Score = 92 },
            new Student { Id = 3, Name = "이영희", Score = 78 },
            new Student { Id = 4, Name = "박민수", Score = 95 },
            new Student { Id = 5, Name = "최지혜", Score = 88 }
        };

        // LINQ 쿼리를 사용해 데이터를 처리하는 방법을 아래에서 배웁니다.
    }
}

// 학생 클래스를 정의
class Student
{
    public int Id { get; set; } // 학생 ID
    public string Name { get; set; } // 이름
    public int Score { get; set; } // 점수
}
 

(1) Query Syntax (쿼리 문법)

SQL과 유사한 문법으로 데이터를 처리합니다.

// 80점 이상인 학생 필터링 (Query Syntax 사용)
var highScorers = from student in students
                  where student.Score >= 80
                  select student;

Console.WriteLine("80점 이상인 학생:");
foreach (var student in highScorers)
{
    Console.WriteLine($"{student.Name} (점수: {student.Score})");
}
 

(2) Method Syntax (메서드 문법)

C# 메서드 체인을 사용하여 데이터를 처리합니다.

// 80점 이상인 학생 필터링 (Method Syntax 사용)
var highScorers = students.Where(student => student.Score >= 80);

Console.WriteLine("80점 이상인 학생:");
foreach (var student in highScorers)
{
    Console.WriteLine($"{student.Name} (점수: {student.Score})");
}
 
 

추가 LINQ 연산자 예제

정렬: 점수 순으로 학생 정렬

var sortedStudents = students.OrderBy(student => student.Score);

Console.WriteLine("점수 순으로 정렬된 학생:");
foreach (var student in sortedStudents)
{
    Console.WriteLine($"{student.Name} (점수: {student.Score})");
}
 
 
 

데이터 변환: 이름만 추출

 
var names = students.Select(student => student.Name);

Console.WriteLine("학생 이름 목록:");
foreach (var name in names)
{
    Console.WriteLine(name);
}

 

그룹화: 점수 기준 그룹화

 
var groupedStudents = students.GroupBy(student => student.Score / 10);

Console.WriteLine("점수대별 학생 그룹:");
foreach (var group in groupedStudents)
{
    Console.WriteLine($"점수대: {group.Key * 10}점대");
    foreach (var student in group)
    {
        Console.WriteLine($"  - {student.Name} (점수: {student.Score})");
    }
}
 

💡 LINQ는 데이터를 필터링, 정렬, 변환, 그룹화 등 다양한 방식으로 처리할 수 있는 강력한 연산자를 제공합니다.

 


3. IEnumerable과 IQueryable 인터페이스

LINQ는 두 가지 주요 인터페이스인 **IEnumerable**과 **IQueryable**을 통해 데이터를 처리합니다. 두 인터페이스의 차이를 이해하면 LINQ를 더 효과적으로 사용할 수 있습니다.

IEnumerable

  • 데이터 소스: 컬렉션과 같은 메모리 내 데이터.
  • 즉시 실행: 쿼리를 호출할 때 데이터가 즉시 실행됩니다.
  • 적용: 메모리 내의 데이터 소스 (예: List, Array)에서 주로 사용됩니다.
var enumerableQuery = students.Where(student => student.Score >= 80);

Console.WriteLine("IEnumerable 사용:");
foreach (var student in enumerableQuery)
{
    Console.WriteLine($"{student.Name} (점수: {student.Score})");
}
 
 

IQueryable

  • 데이터 소스: 데이터베이스와 같은 외부 데이터 소스.
  • 지연 실행: 쿼리가 실행될 때까지 데이터 처리가 지연됩니다.
  • 적용: 데이터베이스 연동 기술 (예: Entity Framework)에서 주로 사용됩니다.

 

// 예: Entity Framework를 사용하는 경우
using (var context = new SchoolContext())
{
    IQueryable<Student> queryableQuery = context.Students.Where(student => student.Score >= 80);

    Console.WriteLine("IQueryable 사용:");
    foreach (var student in queryableQuery)
    {
        Console.WriteLine($"{student.Name} (점수: {student.Score})");
    }
}

 

주요 차이점 요약

 

특징 IEnumerable IQueryable
데이터 소스 메모리 내 데이터 데이터베이스, 웹 서비스 등 외부 소스
실행 방식 즉시 실행 지연 실행
사용 사례 컬렉션, 배열 LINQ to SQL, Entity Framework

💡 메모리 내 데이터에는 IEnumerable, 데이터베이스와 같은 외부 데이터에는 IQueryable을 사용하는 것이 일반적입니다.


LINQ의 성능과 최적화

  1. 지연 실행 (Deferred Execution)
    LINQ 쿼리는 필요할 때까지 실행되지 않습니다. ToList()나 ToArray()를 호출하면 즉시 실행됩니다.
    var query = students.Where(student => student.Score >= 80); // 지연 실행
    var result = query.ToList(); // 즉시 실행

  2. 효율적인 필터링
    데이터가 많을수록 필터 조건을 처음에 사용하는 것이 성능에 유리합니다.

    var optimizedQuery = students.Where(s => s.Score >= 80).OrderBy(s => s.Name);



  3. 캐싱 사용
    동일한 쿼리를 여러 번 실행할 경우, 결과를 캐싱하여 성능을 개선할 수 있습니다.

 

 

728x90
반응형