LINQ Query Expression(쿼리 식)에 대해서 설명하고 있다.
이번 시간에는 조금 더 구체적으로 쿼리식을 만드는 방법을 설명하겠다.
이전 게시물에서 LINQ 쿼리 식을 만드는 몇 가지 규칙에 대해서 설명하였으니 참고하기 바란다.
2023.11.07 - [C# (.Net)/LINQ] - C#의 핵심은 LINQ입니다. LINQ 알아보기
2023.11.09 - [C# (.Net)/LINQ] - LINQ 쿼리(Query)란? - SQL 인 듯 아닌 듯, 개념부터 알아가기
2023.11.13 - [C# (.Net)/LINQ] - LINQ Query Expression (쿼리 식), 쿼리 변수 배우기
LINQ Query Expression (쿼리식) 배우기
from 절 (쿼리식 시작)
- LINQ 쿼리 식은 from으로 시작해야 하고,
- . (dot)을 통해서 객체의 멤버변수를 접근할 수 있다.
- 쿼리식에는 여러 개의 from 절을 사용할 수 있다.
IEnumerable<Student> querySyntax =
from school in schools //from으로 시작
from student in school.Students //여러개의 from 사용 가능
where student.Age > 10 // . (dot)을 이용한 멤버 변수 접근
select student;
select, group (쿼리식 종료)
- LINQ 쿼리 식 종료는 select 또는 group으로 종료한다.
group 절
group으로 사용할 key는 문자, 숫자 등 어떤 데이터 형식이든 가능하다.
var queryGroup =
from exam in exams
group exam by exam.Point;
select 절
개체 형식을 반환한다. new 키워드를 통해서 새로운 형태로 반환도 가능하다.
이렇게 변환하는 것을 projection (프로젝션)이라 한다.
SQL의 as (alias) 구문과 유사하다.
var queryList =
from exam in exams
select exam;
var queryList2 =
from exam in exams
where exam.Point > 90
select new
{
Major = exam.Subject,
Pts = exam.Point,
Grade = 1
};
into 키워드
select 또는 group 절을 사용 시 into 키워드를 통해서 임시로 새로운 그룹으로 만들어서 사용할 수 있다.
프로그램으로 표현하면 loop 안에 loop로 반복되는 집합으로 생각하면 쉽다.
아래의 예제는 90점 이상인 목록을 그룹화한 후 groupA 넣은 후 반환하기 때문에
두 개의 foreach를 통해서 해당 값을 가져올 수 있다.
List<Exam> exams = new List<Exam>();
exams.Add(new Exam { Subject = "국어", Point = 100 });
exams.Add(new Exam { Subject = "영어", Point = 95 });
exams.Add(new Exam { Subject = "수학", Point = 85 });
exams.Add(new Exam { Subject = "과학", Point = 80 });
exams.Add(new Exam { Subject = "체육", Point = 95 });
//90점 이상인 과목을 그룹핑하여 groupA로 넣고
//groupA를 반환한다
var queryGroup =
from exam in exams
where exam.Point >= 90
group exam by exam.Point into groupA
select groupA;
foreach (var group in queryGroup)
{
System.Diagnostics.Debug.WriteLine($"group.Key = {group.Key}");
foreach (var subItem in group)
{
System.Diagnostics.Debug.WriteLine($"{subItem.Subject} = {subItem.Point}");
}
}
//결과
group.Key = 100
국어 = 100
group.Key = 95
영어 = 95
체육 = 95
where 절 (필터링 filtering, 조건)
from과 select, group 사이에 필터링, 정렬, 조인절을 넣어서 사용한다.
당연히 여러 개의 조건절을 사용할 수 있으며 and 조건은 &&, or 조건은 || 으로 표시한다.
// and = &&
var queryGroup =
from exam in exams
where exam.Point >= 90 && exam.Subject == "국어"
select exam;
// or = ||
var queryGroup2 =
from exam in exams
where exam.Subject == "국어" || exam.Subject == "영어"
select exam;
orderby 절 (정렬)
정렬을 하려면 orderby를 사용한다. 정렬할 속성을 입력 후 ascending (오름차순), descending (내림차순)을 입력한다.
ascending 키워드는 선택 사항이며, 순서가 지정되지 않은 경우 생략할 경우 오름 차순으로 정렬된다.
순차적으로 입력 시 1차 정렬 후, 2차 정렬 형태로 처리된다.
var queryGroup =
from exam in exams
orderby exam.Subject ascending, exam.Point descending
select exam;
join 절 (요소 연결)
SQL의 join은 테이블과 테이블을 공통된 field 값으로 연결할 경우 사용하는데, LINQ에서도 같은 형태로 사용할 수 있다.
다만, LINQ 특징 상 여러 개의 데이터소스를 사용하여 연결할 수 있어서 SQL보다 활용 및 확장성이 더 높다.
//클래스 정의
public class Exam
{
public string Subject { get; set; }
public int Point { get; set; }
}
public class Teacher
{
public string Major { get; set; }
public string Name { get; set; }
}
//데이터 소스 처리
List<Exam> exams = new List<Exam>();
exams.Add(new Exam { Subject = "국어", Point = 100 });
exams.Add(new Exam { Subject = "영어", Point = 95 });
exams.Add(new Exam { Subject = "수학", Point = 85 });
exams.Add(new Exam { Subject = "과학", Point = 80 });
exams.Add(new Exam { Subject = "체육", Point = 95 });
//데이터 소스 처리
List<Teacher> teachers = new List<Teacher>();
teachers.Add(new Teacher { Major = "국어", Name = "홍길동" });
teachers.Add(new Teacher { Major = "영어", Name = "유능한" });
teachers.Add(new Teacher { Major = "수학", Name = "정확한" });
teachers.Add(new Teacher { Major = "과학", Name = "최박식" });
teachers.Add(new Teacher { Major = "체육", Name = "김건강" });
//join 절
var queryGroup =
from exam in exams
join teacher in teachers on exam.Subject equals teacher.Major
orderby exam.Subject ascending, exam.Point descending
select new
{
TeacherName = teacher.Name,
Point = exam.Point
};
//실행
foreach (var item in queryGroup)
{
System.Diagnostics.Debug.WriteLine(item);
}
//결과
{ TeacherName = 최박식, Point = 80 }
{ TeacherName = 홍길동, Point = 100 }
{ TeacherName = 정확한, Point = 85 }
{ TeacherName = 유능한, Point = 95 }
{ TeacherName = 김건강, Point = 95 }
let 절 (변수 저장)
LINQ에서 변수를 처리하는 특수한 let 절이 있는데 이런저런 설명보다는 소스를 통해서 이해하는 편이 좋다.
문자열 처리뿐 아니라 여러 가지 메서드 호출하여 사용한다.
var queryGroup =
from exam in exams
let allSubject = "과목명 : " + exam.Subject
select allSubject;
foreach (var item in queryGroup)
{
System.Diagnostics.Debug.WriteLine(item);
}
//결과
과목명 : 국어
과목명 : 영어
과목명 : 수학
과목명 : 과학
과목명 : 체육
서브 쿼리 (Subqueries)
SQL처럼 하위 쿼리 형태로 사용할 수 있지만,
개인적 경험을 비춰보면 LINQ로 하위 쿼리 사용하면 가독성이 너무 떨어져서 로직 파악이 어려워서
junior 개발자들에게는 추천하지 않는다.
서브 쿼리는 추후 쿼리 상세 내용에서 소개하도록 하겠다.
이번 시간에는 LINQ에서 거의 필수적으로 사용하는 쿼리 표현식에 대해서 알아보았습니다.
SQL과 비슷하면서 다르기 때문에 쉬운 듯 어려운 듯한 것 같습니다.
대디동동의 코딩 강좌를 통해서 Junior 개발자에게 많은 도움을 드릴 수 있도록 하겠습니다.
'코딩강좌 > LINQ' 카테고리의 다른 글
LINQ - ToList, ToArray, ToDictionary, ToLookup 알아보기 (1) | 2023.12.29 |
---|---|
LINQ Query Expression (쿼리 식), 쿼리 변수 배우기 (0) | 2023.11.13 |
LINQ 쿼리(Query)란? - SQL 인 듯 아닌 듯, 개념부터 알아가기 (1) | 2023.11.09 |
C#의 핵심은 LINQ입니다. LINQ 알아보기 (0) | 2023.11.07 |