자바스크립트를 허용해주세요.
[ 자바스크립트 활성화 방법 ]
from Mohon Aktifkan Javascript!
 

[C#] 14장 LINQ 기본 -> 고급쿼리

728x90

✅ 1. LinQ란?

LINQ(Language Integrated Query)는 C#에 데이터 컬렉션(List,Array, Dictionary 등)이나 DB(Entity Framwork 등)에 쿼리 스타일로 접근할 수 있게 해주는 강력한 기능입니다.


✅ 2. 그룹화(Grouping)

그룹화(Grouping)은 특정 데이터를 특정한 키로 묶어 그룹별로 집계할 수 있게 도와주는 기능입니다. 

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

public class Movies
{ 
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public double Rating { get; set; }

}

public class Group
{
    public static void Main(String[] args)
    {
        // 영화 List 생성
        var movies = new List<Movies>()
        {
            new Movies { Title = "극장판 귀멸의 칼날: 무한성편", ReleaseDate = new DateTime(2025,08,22) , Rating= 9.07 },
            new Movies { Title = "F1 더 무비", ReleaseDate = new DateTime(2025,06,25), Rating=9.07},
            new Movies { Title = "악마가 이사왔다", ReleaseDate = new DateTime(2025,08,13), Rating=6.95},
        };

        while (true)
        {
            Console.Clear();
            // 영화 선택해서 찾아보기
            Console.WriteLine("조회하실 영화 제목을 입력해주세요:");
            foreach (var movie in movies)
            {
                Console.WriteLine($"- {movie.Title}");
            }

            // 검색할 영화 제목입력
            Console.WriteLine("\n영화 제목 입력: ");
            var inputMovieTitle = Console.ReadLine()?.Trim();

            // 공백 처리
            if (string.IsNullOrEmpty(inputMovieTitle))
            {
                Console.WriteLine("영화 제목을 입력해주세요.");
                Console.ReadKey();
                continue;
            }

            // 종료 처리
            if (inputMovieTitle.Equals("exit", StringComparison.OrdinalIgnoreCase)) 
            {
                Console.WriteLine("프로그램을 종료합니다.");
                break;

            }

            // 공백 제거후 소문자로 비교
            var normalizedInput = inputMovieTitle.Replace(" ", "").ToLower();

            // 입력한 영화 제목으로 영화 찾기 = indexOf와 Whtere를 사용해 유사한 영화 제목도 검색 
            var selectedMovie = movies.Where(m => m.Title.Replace(" ", "").ToLower().Contains(normalizedInput)).ToList();

            if (selectedMovie.Count == 0)
            {
                Console.WriteLine($"\n '{inputMovieTitle}'은 없거나 개봉하지 않았습니다.");
            }
            else if (selectedMovie.Count == 1)
            {
                var movie = selectedMovie[0];
                Console.WriteLine($"\n{movie.Title}의 개봉일: {movie.ReleaseDate:yyyy-MM-dd}, 평점: {movie.Rating:F3}");
            }
            else
            {
                Console.WriteLine($"\n 입력하신 결과는 다음과 같습니다 선택: ");
                for (int i = 0; i < selectedMovie.Count; i++)
                {
                    Console.WriteLine($"{i + 1}. {selectedMovie[i].Title}");
                }

                Console.WriteLine("\n 번호를 입력해 주세요:");
                if (int.TryParse(Console.ReadLine(), out int choice) && choice >= 1 && choice <= selectedMovie.Count)
                {
                    var movie = selectedMovie[choice - 1];
                    Console.WriteLine($"\n{movie.Title}의 개봉일: {movie.ReleaseDate:yyyy-MM-dd}, 평점: {movie.Rating:F3}");
                }
                else
                {
                    Console.WriteLine("다시 선택해 주세요");
                }
            }
            Console.WriteLine("\n 계속 검색하려면 아무키나 입력하세요");
            Console.ReadKey();
        }

    }
}

✅ 3. 조인 (Join / Left Join)

두 개 이상의 컬렉션을 키 값 기준으로 연결하여 내부 또는 외부 조인을 수행하는 기능입니다.

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

public class Students
{
    public string Name;
    public string Class;
    public int Score;
}

class Program
{
     static void Main()
    {
        var students = new List<Students>
        {
            new Students { Name="Kim", Class="A", Score=90},
            new Students { Name="James", Class="A", Score=95},
            new Students { Name="Park", Class="B", Score=85},
            new Students { Name="James", Class="B", Score=80},

        };

        var awards = new List<(string Name, string Award)>
        {
            ("Kim", "Math Olympiad"),
        };

        var joinQuery = from s in students
                        join a in awards on s.Name equals a.Name into gj
                        from sub in gj.DefaultIfEmpty()
                        select new { s.Name, s.Score, Award = sub.Award ?? "None" };

        Console.WriteLine("\n== 학생 & 수상 정보 ===");
        foreach (var item in joinQuery)
            Console.WriteLine($"{item.Name} - {item.Score}, Award: {item.Award}");

    }
}
  • DB 테이블이나 외부 데이터와 컬렉션 연결 시 유용함

✅ 4. 다중 form / SelectMany (Cross Join)

두 개 이상의 컬렉션을 곱집합 형태로 결합하여 모든 조합을 생성할 수 있음

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var colors = new[] { "Red", "Blue" };
        var sizes = new[] { "s", "M" };

        var products = from c in colors
                       from s in sizes
                       select new { Color = c, Size = s };

        Console.WriteLine("\n== 색상+사이즈 조합 ===");
        foreach (var p in products)
            Console.WriteLine($"{p.Color} - {p.Size}");
    }
}
  • 제품 옵션 포함, 곱집합 데이터 생성 시 활용

✅ 5. 집합 연산 (Union / Intersect / Except / Distinct)

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var list1 = new[] { 1, 2, 3, 4 };
        var list2 = new[] { 3, 4, 5, 6};

        Console.WriteLine("\n=== 집합 연산 ===");
        Console.WriteLine("합집합: " + string.Join(",", list1.Union(list2)));
        Console.WriteLine("교집합: " + string.Join(",", list1.Intersect(list2)));
        Console.WriteLine("차집합: " + string.Join(",", list1.Except(list2)));
        Console.WriteLine("중복 제거: " + string.Join(",", new[] { 1, 2, 2, 3, 4, 4 }.Distinct()));
    }
}
  • 중복 제거, 데이터 비교, 필터링 시 유용

✅ 6. 다중 정렬 (OrderBy + ThenBy)

컬렉션을 다중 조건으로 정렬할 수 있는 기능입니다.

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

public class Primers
{
    public string Team { get; set; }
    public int Games { get; set; }
    public int Wins { get; set; }
    public int Draws { get; set; }
    public int Losses { get; set; }
    public int GoalsFor { get; set; }
    public int GoalsAgainst { get; set; }
    public int GoalDifference => GoalsFor - GoalsAgainst;
    public int Points => Wins * 3 + Draws;

}

class Program
{
    static void Main()
    {
        var big4 = new List<Primers>
        {
            new Primers { Team = "Chelsea", Games = 3, Wins = 2, Draws = 1, Losses = 0, GoalsFor = 7, GoalsAgainst = 1},
            new Primers { Team = "Arsenal", Games = 2, Wins = 2, Draws = 0, Losses = 0, GoalsFor = 6, GoalsAgainst = 0},
            new Primers { Team = "Tottenham Hotspur", Games = 3, Wins = 2, Draws = 0, Losses = 1, GoalsFor = 5, GoalsAgainst = 1 },
            new Primers { Team = "Liverpool", Games = 2, Wins = 2, Draws = 0, Losses = 0, GoalsFor = 7, GoalsAgainst = 4}
        };

        var ranking = big4
            .OrderByDescending(t => t.Points)
            .ThenByDescending(t => t.GoalDifference)
            .ThenByDescending(t => t.GoalsFor)
            .ToList();

        Console.WriteLine("\n=== 2025/26 프리미어리그 Big4 ===");
        Console.WriteLine("{0,-4} | {1,-20} | {2,6} | {3,3} | {4,3} | {5,3} | {6,5} | {7,5} | {8,7} | {9,5}",
            "순위","팀","경기수","승","무","패","득점","실점","득실차","승점");


        for (int i = 0; i < ranking.Count; i++)
        {
            var t = ranking[i];
            Console.WriteLine("{0,-6} | {1,-21} | {2,9} | {3,4} | {4,4} | {5,4} | {6,7} | {7,7} | {8,10} | {9,5}",
                 i + 1, t.Team, t.Games, t.Wins, t.Draws, t.Losses, t.GoalsFor, t.GoalsAgainst, t.GoalDifference, t.Points
                );

        }
    }
}
=== 2025/26 프리미어리그 Big4 ===
순위   | 팀                    |    경기수 |   승 |   무 |   패 |    득점 |    실점  |     득실차 |   승점
1      | Chelsea               |        3 |    2 |    1 |    0 |       7 |       1 |          6 |     7
2      | Arsenal               |        2 |    2 |    0 |    0 |       6 |       0 |          6 |     6
3      | Tottenham Hotspur     |        3 |    2 |    0 |    1 |       5 |       1 |          4 |     6
4      | Liverpool             |        2 |    2 |    0 |    0 |       7 |       4 |          3 |     6
  • 순위표, 리스트 정렬 시 활용

✅ 7. Let 키워드

쿼리 문법에서 중간 계산 결과를 변수처럼 저장하여 가독성을 높이는 기능입니다.

public class Students
{
    public string Name;
    public string Class;
    public int Speed;



    class Program
    {
        static void Main()
        {
            var students = new List<Students>
        {
            new Students { Name="Kim", Class="A", Speed=80},
            new Students { Name="James", Class="A", Speed=80},
            new Students { Name="Park", Class="B", Speed=90},
            new Students { Name="James", Class="B", Speed=75}
        };

            var query = from s in students
                        let grade = s.Speed >= 90 ? "과속" : "통과"
                        select new { s.Name, s.Speed, Grade = grade };
            Console.WriteLine("\n==== 전방에 80km 과속단속 구간입니다. ===");
            foreach (var s in query)
                Console.WriteLine($"{s.Name} - {s.Speed} - {s.Grade}");
        }
    }
}
  • 중간 계산 결과를 재사용할 때 코드 가독성 향상

☑️ 8. 지연 실행 vs 즉시 실행

LINQ 쿼리는 기본적으로 지연 실행되어 실제 데이터 접근 시 계산, ToLis() 등을 사용하면 즉시 실행가능

using System;
using System.Linq;

class Program
{
  static void Main()
    {
        var numbers = Enumerable.Range(1, 10);

        // 지연 실행
        var query = numbers.Where(n => n > 5);

        // 즉시 실행
        var list = query.ToList();

        Console.WriteLine("\n=== 지연 실행 vs 즉시 실행 ===");
        Console.WriteLine("Query 결과: " + string.Join(",", query));
        Console.WriteLine("List 결과: " + string.Join(",", list));
    }
}

☑️ 정리 

  • 순서대로 고급 기능 중심: GroupBy -> Join -> Cross Join > 집합 -> 정렬 -> Let -> 실행 방식
  • 실무에서는 DB, API, 컬렉션, 보고서, 데이터 분석에 바로 활용
  • LINQ 쿼리 문법과 메서드 체이닝을 자유롭게 변환 가능

 

 

GitHub - Koras02/Csharp-posting: https://thinky.tistory.com/category/%EA%B2%8C%EC%9E%84%20%EB%AA%A8%EB%94%A9/C%23

https://thinky.tistory.com/category/%EA%B2%8C%EC%9E%84%20%EB%AA%A8%EB%94%A9/C%23 - Koras02/Csharp-posting

github.com

 

728x90
LIST

'게임 모딩 > C#' 카테고리의 다른 글

[C#] 16장 패턴일치 심화  (0) 2025.09.10
[C#] 15장 제네릭 심화  (0) 2025.09.05
[C#] 13장 C# 람다식과 Func  (0) 2025.08.24
[C#] 12장 C# 델리게이트와 이벤트  (0) 2025.08.20
[C#] 11장. C# 예외 처리  (1) 2025.08.18