본문 바로가기
Study/C#

C# 9편: LINQ로 데이터 검색, 필터링, 변환하기

by wawManager 2024. 10. 28.
728x90

1. LINQ란?

LINQ(Language Integrated Query)는 C#에서 데이터 집합을 질의하고 조작할 수 있도록 하는 기능입니다. LINQ는 배열, 리스트, 데이터베이스, XML, 컬렉션 등의 다양한 데이터 소스에 쿼리를 적용할 수 있습니다. SQL과 유사한 방식으로 데이터를 필터링하고, 정렬하고, 변환할 수 있으며, C# 언어에 통합되어 매우 편리합니다.

2. LINQ 기본 문법

LINQ는 두 가지 방식으로 사용할 수 있습니다: **쿼리 구문(Query Syntax)**과 메서드 구문(Method Syntax). 두 가지 방식 모두 동일한 결과를 얻을 수 있지만, 상황에 따라 더 적합한 방식을 선택하면 됩니다.

LINQ 쿼리 구문 기본 구조

var 결과 = from 변수 in 데이터소스
           where 조건
           select 변수;

LINQ 메서드 구문 기본 구조

var 결과 = 데이터소스.Where(조건).Select(변수);

3. LINQ 쿼리 구문 예시

LINQ 쿼리 구문을 사용하여 배열에서 짝수를 필터링하는 간단한 예제를 살펴보겠습니다.

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        // LINQ 쿼리 구문
        var evenNumbers = from number in numbers
                          where number % 2 == 0
                          select number;

        Console.WriteLine("짝수 목록:");
        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

결과:

짝수 목록:
2
4
6
8
10

4. LINQ 메서드 구문 예시

같은 결과를 메서드 구문으로도 표현할 수 있습니다. 메서드 구문은 메서드 체이닝 방식으로 데이터를 처리하는 것이 특징입니다.

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        // LINQ 메서드 구문
        var evenNumbers = numbers.Where(number => number % 2 == 0);

        Console.WriteLine("짝수 목록:");
        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

5. LINQ의 주요 메서드

LINQ에는 데이터를 쉽게 다룰 수 있도록 다양한 메서드가 포함되어 있습니다. 몇 가지 중요한 메서드를 살펴보겠습니다.

1) Where: 조건을 만족하는 요소를 필터링합니다.

var evenNumbers = numbers.Where(n => n % 2 == 0);

2) Select: 데이터를 변환하거나 특정 필드만 선택합니다.

var squares = numbers.Select(n => n * n);

3) OrderBy / OrderByDescending: 데이터를 오름차순 또는 내림차순으로 정렬합니다.

var sortedNumbers = numbers.OrderBy(n => n);
var descendingNumbers = numbers.OrderByDescending(n => n);

4) First / FirstOrDefault: 조건을 만족하는 첫 번째 요소를 반환합니다. 없으면 예외를 던지거나 null을 반환합니다.

var firstEven = numbers.First(n => n % 2 == 0); // 첫 번째 짝수

5) Take / Skip: 앞에서부터 특정 개수의 요소를 선택하거나 건너뜁니다.

var firstThree = numbers.Take(3); // 처음 3개의 요소
var skipThree = numbers.Skip(3); // 처음 3개의 요소를 건너뜀

6) Aggregate: 누적 연산을 수행합니다. (예: 합계, 곱셈, 문자열 연결)

var sum = numbers.Aggregate((a, b) => a + b); // 배열의 합계

7) Distinct: 중복 요소를 제거하고 고유한 값만 반환합니다.

var distinctNumbers = numbers.Distinct();

8) Any / All: 조건을 만족하는 요소가 있는지 확인하거나, 모든 요소가 조건을 만족하는지 확인합니다.

bool hasEven = numbers.Any(n => n % 2 == 0); // 짝수가 있는지 확인
bool allPositive = numbers.All(n => n > 0);  // 모든 숫자가 양수인지 확인

6. LINQ를 사용한 객체 데이터 처리

LINQ는 객체 컬렉션에서도 매우 유용하게 사용됩니다. 예를 들어, 학생 목록에서 성적이 80점 이상인 학생을 필터링하는 예제를 살펴보겠습니다.

using System;
using System.Collections.Generic;
using System.Linq;

class Student
{
    public string Name { get; set; }
    public int Score { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<Student> students = new List<Student>
        {
            new Student { Name = "Alice", Score = 85 },
            new Student { Name = "Bob", Score = 75 },
            new Student { Name = "Charlie", Score = 90 }
        };

        // LINQ 쿼리 구문
        var highScorers = from student in students
                          where student.Score >= 80
                          select student;

        // LINQ 메서드 구문
        var highScorersMethod = students.Where(s => s.Score >= 80);

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

결과:

성적이 80점 이상인 학생들:
Alice: 85
Charlie: 90

7. 익명 객체와 LINQ

LINQ에서는 익명 객체를 사용할 수 있습니다. 익명 객체는 새로운 클래스를 정의하지 않고, 임시로 데이터 필드를 묶을 수 있는 기능을 제공합니다.

예시: 익명 객체 사용

var highScorers = from student in students
                  where student.Score >= 80
                  select new { student.Name, student.Score };

foreach (var student in highScorers)
{
    Console.WriteLine($"{student.Name}: {student.Score}");
}

8. LINQ의 Deferred Execution(지연 실행)

LINQ 쿼리는 지연 실행을 지원합니다. 즉, 실제로 데이터를 요청할 때(예: foreach로 순회할 때) 쿼리가 실행됩니다. 이를 통해 불필요한 데이터 처리를 방지하고 성능을 최적화할 수 있습니다.

지연 실행 예시

var query = numbers.Where(n => n > 5); // 이 시점에서 쿼리는 실행되지 않음

실제 쿼리가 실행되는 시점은 데이터를 순회하거나 ToList, ToArray와 같은 메서드로 데이터를 구체화할 때입니다.

foreach (var number in query)
{
    Console.WriteLine(number); // 이 시점에서 쿼리가 실행됨
}

9. LINQ to SQL 및 LINQ to Entities

LINQ는 단순히 메모리 내 컬렉션뿐만 아니라 SQL 데이터베이스 또는 Entity Framework와 같은 ORM에서 데이터를 질의할 때도 사용할 수 있습니다. 이를 각각 LINQ to SQL, LINQ to Entities라고 부릅니다.

using (var db = new SchoolContext())
{
    var students = from s in db.Students
                   where s.Score >= 80
                   select s;

    foreach (var student in students)
    {
        Console.WriteLine($"{student.Name}: {student.Score}");
    }
}

C# 9편: LINQ(쿼리 구문) - 데이터를 쉽게 처리하기

제목: C# LINQ로 데이터 검색, 필터링, 변환하기


1. LINQ란?

LINQ(Language Integrated Query)는 C#에서 데이터 집합을 질의하고 조작할 수 있도록 하는 기능입니다. LINQ는 배열, 리스트, 데이터베이스, XML, 컬렉션 등의 다양한 데이터 소스에 쿼리를 적용할 수 있습니다. SQL과 유사한 방식으로 데이터를 필터링하고, 정렬하고, 변환할 수 있으며, C# 언어에 통합되어 매우 편리합니다.

2. LINQ 기본 문법

LINQ는 두 가지 방식으로 사용할 수 있습니다: **쿼리 구문(Query Syntax)**과 메서드 구문(Method Syntax). 두 가지 방식 모두 동일한 결과를 얻을 수 있지만, 상황에 따라 더 적합한 방식을 선택하면 됩니다.

LINQ 쿼리 구문 기본 구조

csharp
코드 복사
var 결과 = from 변수 in 데이터소스 where 조건 select 변수;

LINQ 메서드 구문 기본 구조

csharp
코드 복사
var 결과 = 데이터소스.Where(조건).Select(변수);

3. LINQ 쿼리 구문 예시

LINQ 쿼리 구문을 사용하여 배열에서 짝수를 필터링하는 간단한 예제를 살펴보겠습니다.

csharp
코드 복사
using System; using System.Linq; class Program { static void Main(string[] args) { int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // LINQ 쿼리 구문 var evenNumbers = from number in numbers where number % 2 == 0 select number; Console.WriteLine("짝수 목록:"); foreach (var number in evenNumbers) { Console.WriteLine(number); } } }

결과:

코드 복사
짝수 목록: 2 4 6 8 10

4. LINQ 메서드 구문 예시

같은 결과를 메서드 구문으로도 표현할 수 있습니다. 메서드 구문은 메서드 체이닝 방식으로 데이터를 처리하는 것이 특징입니다.

csharp
코드 복사
using System; using System.Linq; class Program { static void Main(string[] args) { int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // LINQ 메서드 구문 var evenNumbers = numbers.Where(number => number % 2 == 0); Console.WriteLine("짝수 목록:"); foreach (var number in evenNumbers) { Console.WriteLine(number); } } }

5. LINQ의 주요 메서드

LINQ에는 데이터를 쉽게 다룰 수 있도록 다양한 메서드가 포함되어 있습니다. 몇 가지 중요한 메서드를 살펴보겠습니다.

1) Where: 조건을 만족하는 요소를 필터링합니다.

csharp
코드 복사
var evenNumbers = numbers.Where(n => n % 2 == 0);

2) Select: 데이터를 변환하거나 특정 필드만 선택합니다.

csharp
코드 복사
var squares = numbers.Select(n => n * n);

3) OrderBy / OrderByDescending: 데이터를 오름차순 또는 내림차순으로 정렬합니다.

csharp
코드 복사
var sortedNumbers = numbers.OrderBy(n => n); var descendingNumbers = numbers.OrderByDescending(n => n);

4) First / FirstOrDefault: 조건을 만족하는 첫 번째 요소를 반환합니다. 없으면 예외를 던지거나 null을 반환합니다.

csharp
코드 복사
var firstEven = numbers.First(n => n % 2 == 0); // 첫 번째 짝수

5) Take / Skip: 앞에서부터 특정 개수의 요소를 선택하거나 건너뜁니다.

csharp
코드 복사
var firstThree = numbers.Take(3); // 처음 3개의 요소 var skipThree = numbers.Skip(3); // 처음 3개의 요소를 건너뜀

6) Aggregate: 누적 연산을 수행합니다. (예: 합계, 곱셈, 문자열 연결)

csharp
코드 복사
var sum = numbers.Aggregate((a, b) => a + b); // 배열의 합계

7) Distinct: 중복 요소를 제거하고 고유한 값만 반환합니다.

csharp
코드 복사
var distinctNumbers = numbers.Distinct();

8) Any / All: 조건을 만족하는 요소가 있는지 확인하거나, 모든 요소가 조건을 만족하는지 확인합니다.

csharp
코드 복사
bool hasEven = numbers.Any(n => n % 2 == 0); // 짝수가 있는지 확인 bool allPositive = numbers.All(n => n > 0); // 모든 숫자가 양수인지 확인

6. LINQ를 사용한 객체 데이터 처리

LINQ는 객체 컬렉션에서도 매우 유용하게 사용됩니다. 예를 들어, 학생 목록에서 성적이 80점 이상인 학생을 필터링하는 예제를 살펴보겠습니다.

csharp
코드 복사
using System; using System.Collections.Generic; using System.Linq; class Student { public string Name { get; set; } public int Score { get; set; } } class Program { static void Main(string[] args) { List<Student> students = new List<Student> { new Student { Name = "Alice", Score = 85 }, new Student { Name = "Bob", Score = 75 }, new Student { Name = "Charlie", Score = 90 } }; // LINQ 쿼리 구문 var highScorers = from student in students where student.Score >= 80 select student; // LINQ 메서드 구문 var highScorersMethod = students.Where(s => s.Score >= 80); Console.WriteLine("성적이 80점 이상인 학생들:"); foreach (var student in highScorers) { Console.WriteLine($"{student.Name}: {student.Score}"); } } }

결과:

makefile
코드 복사
성적이 80점 이상인 학생들: Alice: 85 Charlie: 90

7. 익명 객체와 LINQ

LINQ에서는 익명 객체를 사용할 수 있습니다. 익명 객체는 새로운 클래스를 정의하지 않고, 임시로 데이터 필드를 묶을 수 있는 기능을 제공합니다.

예시: 익명 객체 사용

csharp
코드 복사
var highScorers = from student in students where student.Score >= 80 select new { student.Name, student.Score }; foreach (var student in highScorers) { Console.WriteLine($"{student.Name}: {student.Score}"); }

8. LINQ의 Deferred Execution(지연 실행)

LINQ 쿼리는 지연 실행을 지원합니다. 즉, 실제로 데이터를 요청할 때(예: foreach로 순회할 때) 쿼리가 실행됩니다. 이를 통해 불필요한 데이터 처리를 방지하고 성능을 최적화할 수 있습니다.

지연 실행 예시

csharp
코드 복사
var query = numbers.Where(n => n > 5); // 이 시점에서 쿼리는 실행되지 않음

실제 쿼리가 실행되는 시점은 데이터를 순회하거나 ToList, ToArray와 같은 메서드로 데이터를 구체화할 때입니다.

csharp
코드 복사
foreach (var number in query) { Console.WriteLine(number); // 이 시점에서 쿼리가 실행됨 }

9. LINQ to SQL 및 LINQ to Entities

LINQ는 단순히 메모리 내 컬렉션뿐만 아니라 SQL 데이터베이스 또는 Entity Framework와 같은 ORM에서 데이터를 질의할 때도 사용할 수 있습니다. 이를 각각 LINQ to SQL, LINQ to Entities라고 부릅니다.

LINQ to SQL 예시

csharp
코드 복사
using (var db = new SchoolContext()) { var students = from s in db.Students where s.Score >= 80 select s; foreach (var student in students) { Console.WriteLine($"{student.Name}: {student.Score}"); } }

10. 실습 예제: 학생 성적 통계 계산

이번 예제에서는 학생들의 성적 데이터를 바탕으로, LINQ를 이용하여 평균 점수, 최고 점수, 성적이 80점 이상인 학생 수 등을 계산해보겠습니다.

using System;
using System.Collections.Generic;
using System.Linq;

class Student
{
    public string Name { get; set; }
    public int Score { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<Student> students = new List<Student>
        {
            new Student { Name = "Alice", Score = 85 },
            new Student { Name = "Bob", Score = 75 },
            new Student { Name = "Charlie", Score = 90 },
            new Student { Name = "David", Score = 65 },
            new Student { Name = "Eve", Score = 95 }
        };

        // 평균 점수
        double averageScore = students.Average(s => s.Score);
        Console.WriteLine($"평균 점수: {averageScore:F2}");

        // 최고 점수
        int highestScore = students.Max(s => s.Score);
        Console.WriteLine($"최고 점수: {highestScore}");

        // 80점 이상인 학생 수
        int highScorerCount = students.Count(s => s.Score >= 80);
        Console.WriteLine($"80점 이상인 학생 수: {highScorerCount}");
    }
}

결과:

평균 점수: 82.00
최고 점수: 95
80점 이상인 학생 수: 3

11. 요약

  • LINQ는 데이터를 질의하고 조작하는 매우 강력한 도구로, 배열, 리스트, 데이터베이스 등 다양한 소스에 쿼리를 적용할 수 있습니다.
  • 쿼리 구문메서드 구문 모두 동일한 결과를 얻을 수 있으며, 각 상황에 맞는 방식으로 사용할 수 있습니다.
  • 지연 실행을 통해 쿼리는 실제로 필요할 때 실행되며, 성능 최적화에 도움이 됩니다.
  • LINQ는 SQL과 유사한 구문으로 데이터 조작을 직관적으로 할 수 있으며, 데이터 필터링, 정렬, 변환, 통계 등을 쉽게 처리할 수 있습니다.

다음 편에서는 비동기 프로그래밍Task를 다루며, 비동기 작업을 효율적으로 처리하는 방법을 학습하겠습니다.

728x90