지난 게시물에서 LINQ Query에 대한 동작 및 처리 방식에 대해서
1) 데이터 소스 연결, 2) 쿼리(Query) 작성, 3) 쿼리(Query) 실행의 3가지 단계로 구분되며
Count, Max 등 일부 쿼리문을 제외하고 쿼리문을 작성하면 바로 실행되지 않는 지연된 실행을 기본으로 한다고 설명했다.
이번 시간에는 쿼리식에 대한 기본적인 설명을 통해서 LINQ와 SQL Query와의 차이점을 확인하도록 하겠다.
LINQ를 처음 접하는 분들은 아래의 게시물을 학습하면 도움이 되니 읽어 보길 추천한다.
2023.11.07 - [C# (.Net)/LINQ] - C#의 핵심은 LINQ입니다. LINQ 알아보기
2023.11.09 - [C# (.Net)/LINQ] - LINQ 쿼리(Query)란? - SQL 인 듯 아닌 듯, 개념부터 알아가기
쿼리 식(Query Expression) 알아보기
SQL Database의 행(row), XML의 트릭(tree), JSON 등 어떤 형태든지
C# LINQ는 IEnumerable<T> or IQueryable<T> 형태로 반환하여 사용한다는 점만 기억하면 된다.
즉, 객체, 클래스, DataTable, DataSet 등 어떤 형태든지 다룰 수 있다.
쿼리 식(Query Expression)이란?
쿼리 식은 SQL 또는 XQuery와 유사하며 다음과 같은 몇 가지 대표적 규칙을 가지고 있다.
첫 번째, 쿼리 식은 from 절로 시작해야 한다.
두 번째, select 또는 group 절로 끝나야 한다.
세 번째, where, orderby, join, let 절은 from 과 select (group) 사이에 위치한다.
네 번째, into 키워드를 사용하여 join 또는 group 절의 결과로 사용할 수 있다.
List<int> numbers = new List<int> { 1, 5, 2, 8, 3, 9, 4, 6, 7, 10 };
//쿼리 변수 (Query Variable)
IEnumerable<int> oddQuery =
from number in numbers //시작
where number % 2 == 1
orderby number ascending
select number; //끝
쿼리 변수(Query Variable)란?
쿼리 변수란 위에서 설명한 쿼리 식을 저장하는 변수이고, 변수는 쿼리 변수를 통한 결과를 저장한다.
여기에서 중요한 것은 이전 게시물에서 설명한 것처럼 결과를 저장하지 않는다.
지금은 쿼리 변수? 변수? 무슨 말인지 정확히 몰라도 아래 내용을 끝까지 읽으면 이해할 수 있다.
단순히 쿼리식을 저장하기만 하고 실제 실행은 foreach 또는 IEnumerator.MoveNext을 통해서 실행된다.
List<int> numbers = new List<int> { 1, 5, 2, 8, 3, 9, 4, 6, 7, 10 };
//쿼리 변수 (Query Variable)
IEnumerable<int> oddQuery =
from number in numbers
where number % 2 == 1
orderby number ascending
select number;
//이 시점에 LINQ 실행 됨
foreach (var number in oddQuery)
{
Console.WriteLine(number);
}
쿼리 변수는 쿼리 구문(query syntax)과 메서드 구문(method syntax) 또는 이 두 가지를 조합해서 사용하는데,
바로 이점이 강점이자 단점으로 볼 수 있다.
실제, 구글링에 의한 답변에서 query syntax, method syntax 또는 mjxed syntax 가 섞여 있어서
Junior 개발자가 어려움을 느끼는 부분이다.
그럼, 아래의 예제를 보면 그 차이점을 쉽게 확인할 수 있다.
List<Exam> exams = new List<Exam>();
exams.Add(new Exam { Subject = "국어", Point = 90 });
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 });
//쿼리 구문 형태 (Query Syntax)
IEnumerable<Exam> querySyntax =
from exam in exams
where exam.Point > 90
select exam;
//메소드 구문 형태 (Method Based Syntax)
IEnumerable<Exam> queryMethod = exams.Where(x => x.Point > 90);
반면에 다음 예제는 이들은 결과를 저장하기 때문에 쿼리 변수가 아닌 그냥 변수를 나타냅니다.
List<Exam> exams = new List<Exam>();
exams.Add(new Exam { Subject = "국어", Point = 90 });
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<int> numbers = new List<int> { 1, 5, 2, 8, 3, 9, 4, 6, 7, 10 };
int maxNumber = (from number in numbers select number).Max();
//or
IEnumerable<int> query =
from number in numbers
select number;
int maxNumber2 = query.Max();
///////////////////////////////////////////////////////
List<Exam> listExam = (
from exam in exams
where exam.Point > 90
select exam
).ToList();
//or
IEnumerable<Exam> queryList =
from exam in exams
where exam.Point > 90
select exam;
List<Exam> listExam2 = queryList.ToList();
//결과를 가지고 있기 때문에 쿼리 변수가 아닌 변수이다.
쿼리 변수의 명시적 형식 및 암시적 형식
위 예제에서 IEnumerable<int> 또는 IEnumerable<Exam> 형태로 쿼리 변수를 명시적 지정해 주었는데,
var 키워드를 사용하여 컴파일 시간에 쿼리 변수(또는 다른 지역 변수)의 형식을 추론하도록
컴파일러에게 맡길 수 있어서 코딩이 훨씬 편해진다.
대부분 var 형태로 사용하기 때문에 꼭 익혀두길 추천한다.
var queryList =
from exam in exams
where exam.Point > 90
select exam;
이번 게시물에서는 쿼리 식을 사용하는 방법 및 쿼리 변수와 변수의 차이를 알아보았으며,
암시적 형식 변경을 통해 보다 쉽게 코딩하는 방법에 대해서 설명하였고
특히, 쿼리 구문(query syntax)과 메서드 구문(method syntax)의 사용 방식을 꼭 기억하길 바란다.
'코딩강좌 > LINQ' 카테고리의 다른 글
LINQ - ToList, ToArray, ToDictionary, ToLookup 알아보기 (1) | 2023.12.29 |
---|---|
LINQ Query 강좌 - from, select, group, let, join (0) | 2023.11.16 |
LINQ 쿼리(Query)란? - SQL 인 듯 아닌 듯, 개념부터 알아가기 (1) | 2023.11.09 |
C#의 핵심은 LINQ입니다. LINQ 알아보기 (0) | 2023.11.07 |