🔎 LINQ란?

Language Integrated Query의 줄임말로, C# 내부에 내장된 쿼리(Query) 언어입니다.

  • 데이터 집합을 마치 SQL처럼 조회하고 필터링, 정렬, 그룹핑할 수 있습니다.
  • 특히 List, Array, Dictionary, IEnumerable<T> 등에 매우 유용하게 사용됩니다.
  • MS의 Entity Framework나 웹 API 응답 데이터 처리에서도 자주 등장합니다.

🧪 LINQ vs 일반 방식 예제

public enum ClassType { Knight, Archer, Mage }

public class Player
{
    public ClassType ClassType { get; set; }
    public int Level { get; set; }
    public int Hp { get; set; }
    public int Attack { get; set; }
}

✅ 랜덤 플레이어 생성

Random rand = new Random();
List<Player> _players = new List<Player>();

for (int i = 0; i < 100; i++)
{
    ClassType type = (ClassType)rand.Next(0, 3);
    Player player = new Player()
    {
        ClassType = type,
        Level = rand.Next(1, 100),
        Hp = rand.Next(100, 1000),
        Attack = rand.Next(10, 100)
    };
    _players.Add(player);
}

🧵 Q: 레벨이 50 이상인 기사(Knight)만 추출해서, 레벨 오름차순으로 정렬

👣 일반 방식

public static List<Player> GetHighLevelKnights()
{
    List<Player> result = new List<Player>();
    foreach (Player p in _players)
    {
        if (p.ClassType == ClassType.Knight && p.Level >= 50)
            result.Add(p);
    }

    result.Sort((lhs, rhs) => lhs.Level.CompareTo(rhs.Level));
    return result;
}
  • 조건문과 정렬을 직접 구현해야 하기 때문에, 코드가 길고 복잡해집니다.
  • 다른 사람이 보기엔 의도를 파악하기 어려울 수 있습니다.

🌈 LINQ 방식 (Query 구문)

var players =
    from p in _players
    where p.ClassType == ClassType.Knight && p.Level >= 50
    orderby p.Level
    select p;

✔ 해석:

  • from p in _players: foreach (Player p in _players)
  • where: 조건 필터 (Knight, Level >= 50)
  • orderby: 정렬 기준 (Level 오름차순)
  • select: 최종 반환할 데이터 지정

📌 장점: 코드가 짧고, 가독성이 뛰어나며 SQL과 유사한 형식이므로 익숙하다면 배우기 쉽습니다.


🧪 LINQ 문법 구조

구성 요소설명
from데이터 소스 순회 (foreach 역할)
where조건 필터링
orderby정렬 (기본은 ascending)
select결과 추출 (필드 지정도 가능)

🎯 LINQ 심화: 가공된 결과 출력

var players =
    from p in _players
    where p.ClassType == ClassType.Knight && p.Level >= 50
    orderby p.Level
    select new { Hp = p.Hp, Level = p.Level * 2 };
  • select new {}: 익명 타입으로 새로운 가공된 데이터를 반환
  • Level * 2: 연산 처리도 가능

🔁 중첩 from (Nested from)

public class Player
{
    public List<int> Items { get; set; } = new List<int>();
}

// 중첩 from
var playerItems =
    from p in _players
    from item in p.Items
    where item < 30
    select new { p, item };
  • 중첩된 foreach를 LINQ로 표현
  • from p, from item in p.Items: 2중 루프와 동일

🧮 Grouping (SQL의 GROUP BY)

var playersByLevel =
    from p in _players
    group p by p.Level into g
    orderby g.Key
    select g;
  • group by: 특정 필드를 기준으로 그룹화
  • g.Key: 그룹 기준 (여기서는 Level)
  • g: 해당 그룹에 속한 플레이어 집합

🔗 Join (내부 조인, 외부 조인)

List<int> levels = new List<int> { 1, 5, 10 };

var playerLevels =
    from p in _players
    join l in levels on p.Level equals l
    select p;
  • join l in levels on p.Level equals l: p.Levell이 일치하면 조인
  • SQL의 INNER JOIN과 동일한 방식

🔥 LINQ 메서드 구문 (Method Syntax)

var players2 = _players
    .Where(p => p.ClassType == ClassType.Knight && p.Level >= 50)
    .OrderBy(p => p.Level)
    .Select(p => p);
  • Where(), OrderBy(), Select() 등 메서드 체이닝
  • 표준 연산자 방식이라고도 부름
  • 람다식을 활용하여 조건 정의

📌 대부분의 LINQ 연산은 이 방식으로도 동일하게 구현 가능


📌 참고 사이트

LINQ 표준 연산자 문서 (MS 공식 문서):
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable


profile
李家네_공부방

0개의 댓글