LINQ는 .NET에서 데이터를 쿼리처럼 다룰 수 있게 해주는 문법입니다.
List, Array 같은 컬렉션을 대상으로 필터, 정렬, 추출, 그룹핑, 조인까지 간결하게 처리할 수 있어 실무에서 매우 자주 사용됩니다.
린큐는 앞에서 설명했듯이 코드를 쿼리처럼 사용하여 데이터를 쉽게 조회하거나 가공할 수 있게 도와주는 문법입니다.
컬렉션 데이터가 대상이며 컬렉션 데이터는 List, Array 등등 데이터들의 집합을 의미합니다.
린큐를 사용하는 이유는 직관성과 간결화 입니다.
코드를 쿼리처럼 사용하기 때문에 직관적이고 람다와 함께 사용할 경우 반복문 코드를 획기적으로 줄일 수 있습니다.
린큐에서 제공하는 메서드로 필터, 정렬, 그룹핑까지 손쉽게 처리 가능합니다.

린큐 예제 보면서 진행하시죠.
모델(Dto) 생성해서 진행하는게 더 좋을 것 같아서 간단하게 생성해봤습니다.
여기서도 람다식이 등장하는데 (x) => 와 x => 문법은 같은겁니다.
주석 보시면 이해가 편하실거에요.
람다에 들어있는 x 보이시나요? 요게 핵심 입니다.
해당값은 린큐 메서드의 대상이되는 컬렉션(List) 데이터로 아래에서는 dtos 가 되겠네요.
dtos 객체들을 기준으로 린큐 사용이 가능합니다! 이부분이 반복문을 사용하지 않고 코드양을 획기적으로 줄여주는 핵심!
린큐에서 파라미터는 2개까지 허용하는데 1번째는 컬렉션 데이터이고 2번째는 index가 되겠습니다.
주로 (x,y) 형태로 사용합니다.
public class MemoryMan
{
public static void Main()
{
#region 기본
List<Dto> dtos = new List<Dto>
{
new Dto{Age = 10, Name = "영수", No = 2},
new Dto{Age = 20, Name = "영철", No = 3},
new Dto{Age = 30, Name = "영식", No = 1}
};
var filter = dtos.Where((x) => x.Age == 10 || x.Age == 20); // Age 값이 10 or 20 인 데이터만 필터링
var order = dtos.OrderBy(x => x.No); // 오름차순 정렬
var order2 = dtos.OrderByDescending(x => x.No); // 내림차순 정렬
var name = dtos.Select(x => x.Name); // 이름 데이터만 추출
var index = dtos.Where((x, y) => y == 0); // index 0번째 필터링
#endregion
}
public class Dto
{
public int Age { get; set; }
public string Name { get; set; }
public int No { get; set; }
}
}
Where, Select, OrderBy, GroupBy 등등 린큐에서 주로 사용하는 기능에 대해서 알아보겠습니다.
저도 공부하면서 내가 무심코 사용했던 메서드들이 린큐였구나 알게되었네요.
어려운 개념은 아니라 하나씩 정리해보시죠.
그전에 데이터만 조금 추가하도록하겠습니다.
데이터는 나쏠 입니다. 요즘 나쏠을 즐겨보고 있기 때문에...
List<Dto> dtos = new List<Dto>
{
new Dto{Age = 10, Name = "영수", No = 2, Gender=0},
new Dto{Age = 20, Name = "영철", No = 3, Gender=0},
new Dto{Age = 30, Name = "영식", No = 1, Gender = 0},
new Dto{Age = 31, Name = "순자", No = 3, Gender = 1},
new Dto{Age = 29, Name = "영자", No = 2, Gender = 1},
new Dto{Age = 40, Name = "옥순", No = 1, Gender = 1},
};
Where 조건 필터링 입니다. 조건에 맞는 데이터만 필터링 합니다.
var linq_Where = dtos.Where(x => x.Age > 20); // 조건 필터링
Select 는 특정 데이터 추출입니다. 아래 코드 기준으로 Name 데이터만 가져옵니다.
var linq_Select = dtos.Select(x => x.Name); // 데이터 추출
OrderBy 는 정렬 입니다. 특정 키 기준으로 정렬하게 됩니다.
정렬에는 내림차순 오름차순 2가지가 존재하구요.
var linq_Orderby = dtos.OrderBy(x => x.No); // 오름차순
var linq_Orderby_Desc = dtos.OrderByDescending(x => x.No); // 내림차순
요즘 아이들에게 티니피이이 유행이던데요. 개발자들에게 그룹핑이 있습니다.
그룹핑은 특정 키 아래에서는 Gender 를 기준으로 그룹을 나눕니다.
Gender 값이 0과 1 두가지로 나뉩니다.
그룹은 key 로 구분되며 데이터들도 그룹핑되어 나뉩니다.
아래 출력에서는 0번째 그룹이 먼저 출력되고 1번째 그룹이 출력되겠네요.
List<Dto> dtos = new List<Dto>
{
new Dto{Age = 10, Name = "영수", No = 1, Gender=0},
new Dto{Age = 20, Name = "영철", No = 2, Gender=0},
new Dto{Age = 30, Name = "영식", No = 3, Gender = 0},
new Dto{Age = 31, Name = "순자", No = 4, Gender = 1},
new Dto{Age = 29, Name = "영자", No = 5, Gender = 1},
new Dto{Age = 40, Name = "옥순", No = 6, Gender = 1},
};
var linq_Groupby = dtos.GroupBy(x => x.Gender); // 그룹핑
foreach (var group in linq_Groupby)
{
Console.WriteLine("그룹키 : {0}",group.Key);
foreach (var item in group)
{
Console.WriteLine(item.No);
Console.WriteLine(item.Age);
Console.WriteLine(item.Name);
Console.WriteLine(item.Gender);
}
}
조인을 사용하기 위해서 Dto 를 추가하였습니다.
DB 에서 조인은 두 테이블(코드에서는 Dto) 간의 연결을 의미하는데요.
코드에서는 Dto 들의 특정 객체들을 연결합니다. Dto 에서는 No 를 JoinDto 에서는 JoinSeq 를 연결합니다.
연결 시킨 후 마지막에는 추출할 데이터를 지정합니다. (Name, JoinName)
이론적으로 정리하면 No 와 JoinSeq 로 연결하고 실제 데이터는 Name 과 JoinName 을 가져오는겁니다.
List<JoinDto> joinDtos = new List<JoinDto>
{
new JoinDto{JoinSeq = 1, JoinName = "조인_영수" },
new JoinDto{JoinSeq = 99, JoinName = "조인_철수" },
new JoinDto{JoinSeq = 4, JoinName = "조인_순자" },
};
var linq_Join = dtos.Join(joinDtos, dtos => dtos.No, joinDtos => joinDtos.JoinSeq, (dtos, joinDtos) => new { dtos.Name, joinDtos.JoinName});
foreach (var join in linq_Join)
{
Console.WriteLine(join.Name);
Console.WriteLine(join.JoinName);
}
Any 는 제가 값이 있는지 확인하는 용도로 많이 사용한 메서드인데 린큐인줄은 몰랐네요.
값이 1개라도 존재하면 true 0개이면 false return 합니다.
var linq_Any = dtos.Any(x => x.Age > 50); // 해당되는 사항 없으므로 false
var linq_Any2 = dtos.Any(x => x.Age > 30); // 해당되는 데이터가 1개 이상이므로 true
First 는 컬렉션의 1번째 데이터를 가져옵니다.
이 때 주의하셔야할점은 데이터가 0개이면 예외가 발생합니다.
데이터가 0개일 때 예외 발생시키지 않으려면 FirstDefault 사용하시면 됩니다.
FirstDefault 는 데이터가 없으면 null 을 return 합니다.
var linq_First = dtos.First(x => x.Age > 10); // 조건에 맞는 1번째 데이터, 데이터가 없으면 예외 발생
var linq_FirstDefault = dtos.FirstOrDefault(x => x.Age > 50); // 조건에 맞는 1번째 데이터, 데이터가 없으면 null 처리
Single 은 엄격합니다. 데이터가 1개가 아니면 예외를 발생시킵니다.
SingleDefault 는 0개 또는 1개만 허용하며 나머지는 예외를 발생시킵니다.
var linq_single = dtos.Single(x => x.Age > 10); // 데이터가 1개만 존재해야함.
var linq_singleDefault = dtos.SingleOrDefault(x => x.Age > 50); // 데이터가 0~1개 존재해야함.
Distict 는 중복제거 입니다.
아래 소스 기준으로 접근해보면 총 데이터는 6개이고 Gender 값은 0 또는 1 입니다.
Select 로 Gender 값을 추출한 상태에서 중복제거를 적용하면 6개의 Gender 데이터가 0과 1로 줄어듭니다.
이 때 알아둬야하는점은 중복제거를 사용하기 위해서는 기준키가 있어야합니다.
기준키는 2개이상일 수 없고 1개여야하기 때문에 주로 Select 로 키를 추출해서 사용합니다.
List<Dto> dtos = new List<Dto>
{
new Dto{Age = 10, Name = "영수", No = 1, Gender=0},
new Dto{Age = 20, Name = "영철", No = 2, Gender=0},
new Dto{Age = 30, Name = "영식", No = 3, Gender = 0},
new Dto{Age = 31, Name = "순자", No = 4, Gender = 1},
new Dto{Age = 29, Name = "영자", No = 5, Gender = 1},
new Dto{Age = 40, Name = "옥순", No = 6, Gender = 1},
};
var linq_Distinct = dtos.Select(x => x.Gender).Distinct();
나머지 린큐들인데 실무에서 많이 사용했는데 한번 더 놀람!
아래 코드들은 메서드명에서 기능을 유추할 수 있기 때문에 대충 넘어가겠습니다.
var linq_Count = dtos.Count();
var linq_Sum = dtos.Sum(x => x.Age);
var linq_Average = dtos.Average(x => x.Age);
var linq_Max = dtos.Max(x => x.Age);
var linq_Min = dtos.Min(x => x.Age);
린큐 이녀석은 정말 쿼리를 가져온 것 같은 느낌이네요.
기본 쿼리 구조와 람다식을 알고있다면 린큐는 이해하기 수월할 것 같아요.
오늘도 알아가면서 메모리!
'.NET' 카테고리의 다른 글
| .NET 델리게이트(Delegate)란 무엇인가. (0) | 2025.04.15 |
|---|---|
| .NET 람다식(Lambda)란 무엇인가. (0) | 2025.04.10 |
| .NET 데퍼(Dapper)란 무엇인가. (0) | 2025.04.08 |
| .NET 의존성 주입(Dependency Injection) 무엇인가. (0) | 2025.03.28 |
| .NET Serilog 사용 방법 (0) | 2025.01.15 |