C# - LINQ 복습을 위해 작성하는 글 2023-04-20

rizz·2023년 4월 20일
0

C

목록 보기
7/25

📒 갈무리 - LINQ(Language-Integrated Query)

📌 LINQ란?

- 데이터 질의(Query) 기능을 C#에서 사용할 수 있게 해주는 기술

쿼리 기능

- from : 어디에서 찾을 것인지

- where : 조건이 무엇인지

- select : 어떤 것을 가져올 것인지

var QueryData =
	from temp in data
    where temp < 100
    select temp;

📌 LINQ 사용

// C#

            int[] data = new int[] { 1, 2, 3, 4, 5, 100, 101, 102, 103, 104 };

            // LINQ
            var QueryData =
                from temp in data
                where temp < 100
                select temp;

            foreach (int n in QueryData)
            {
                Console.WriteLine("QueryData : " + n);
            }

            // 람다식
            List<int> listData = new List<int>(data);
            List<int> findAllData = listData.FindAll(a => a < 100);

            foreach (int n in findAllData)
            {
                Console.WriteLine("findAllData : " + n);
            }

 

📌 select

- 결과 선택 키워드

- LINQ 쿼리식이 끝나는 부분

- 특정 형식으로 변환 가능

        struct Student
        {
            public int _id;
            public string _name;
            public int _kor;
            public int _eng;

            public Student(int _id, string _name, int _kor, int _eng)
            {
                this._id = _id;
                this._name = _name;
                this._kor = _kor;
                this._eng = _eng;
            }
        }
        static void Main(string[] args)
        {
            Student[] arrStudents =
            {
                new Student(){_id = 100, _name = "John", _kor = 100, _eng = 20},
                new Student(){_id = 200, _name = "Jane", _kor = 80, _eng = 20},
                new Student(300, "Tom", 50, 60),
                new Student(400, "Max", 80, 80),
                new Student(500, "Jac", 70, 70)
            };

            var QueryData =
                from data in arrStudents
                where data._id > 200 && data._kor > 50
                select new
                {
                    id = data._id,
                    name = data._name,
                    total = data._kor + data._eng 
                };
// arrStudents의 데이터에서 data._id > 200 && data._kor > 50 조건에 맞는 데이터들만 모아서 
// id = data._id, name = data._name, total = data._kor + data._eng의 형태로 된 새로운 객체를 만들겠다.

            foreach (var data in QueryData)
            {
                Console.WriteLine("data : " + data.id);
                Console.WriteLine("data : " + data.name);
                Console.WriteLine("data : " + data.total);
                Console.WriteLine();
            }
        }

 

📌 orderby

- 데이터 정렬 키워드

- ascending 오름차순 키워드

- descending 내림차순 키워드

- 컴마를 활용하여 둘 이상의 데이터를 정렬

// C#

            Student[] arrStudents =
            {
                new Student(){_id = 100, _name = "John", _kor = 100, _eng = 20},
                new Student(){_id = 200, _name = "Jane", _kor = 80, _eng = 20},
                new Student(300, "Tom", 50, 60),
                new Student(400, "Max", 80, 80),
                new Student(500, "Jac", 70, 70)
            };

            var QueryData =
                from data in arrStudents
                orderby (data._kor + data._eng) descending // 내림차순 정렬
                // orderby (data._kor + data._eng) ascending // 오름차순 정렬
                select data;

            foreach (var data in QueryData)
            {
                Console.WriteLine("data : " + data._id);
                Console.WriteLine("data : " + data._name);
                Console.WriteLine("data total : " + (data._kor + data._eng));
                Console.WriteLine();
            }
            
Output:
data : 400
data : Max
data total : 160

data : 500
data : Jac
data total : 140

data : 100
data : John
data total : 120

data : 300
data : Tom
data total : 110

data : 200
data : Jane
data total : 100

 

📌 group

- 데이터 분류 후 그룹화하는 키워드

- group A by B into C

- A : 범위, B : 분류 기준, C : 그룹 변수

// C#

            Student[] arrStudents =
            {
                new Student(){_id = 100, _name = "John", _kor = 100, _eng = 20},
                new Student(){_id = 200, _name = "Jane", _kor = 80, _eng = 20},
                new Student(300, "Tom", 50, 60),
                new Student(400, "Max", 80, 80),
                new Student(500, "Jac", 70, 70)
            };

            var QueryData =
                from data in arrStudents
                orderby (data._kor + data._eng) descending // 내림차순 정렬
                group data by (data._kor + data._eng) < 150;
                // 150 보다 작은 집단과 큰 집단으로 분류

            foreach (var data in QueryData)
            {
                // key 값이 bool 값으로 표현
                string str = data.Key ? "합이 150 보다 작은 경우 : " : "합이 150보다 큰 경우 : ";
                Console.WriteLine(str);

                foreach (var item in data)
                {
                    Console.WriteLine($"name : {item._name}, total : {item._kor + item._eng}");
                }
            }
            
Output:
합이 150보다 큰 경우 :
name : Max, total : 160
합이 150 보다 작은 경우 :
name : Jac, total : 140
name : John, total : 120
name : Tom, total : 110
name : Jane, total : 100

into 사용

            var QueryData =
                from data in arrStudents
                // 평균을 구하고 10개의 그룹으로 나눔
                group data by ((data._kor + data._eng) / 2) / 10 into gTemp
                orderby gTemp.Key ascending // 나눈 그룹들을 오름차순으로 정렬
                select gTemp;

            foreach (var data in QueryData)
            {
                // key 값이 숫자
                Console.WriteLine($"data : {data.Key * 10}에서 {(data.Key + 1) * 10}");

                foreach (var item in data)
                {
                    Console.WriteLine($"name : {item._name}, avg : {(item._kor + item._eng) / 2f}");
                }
                Console.WriteLine();
            }

Output:
data : 50에서 60
name : Jane, avg : 50
name : Tom, avg : 55

data : 60에서 70
name : John, avg : 60

data : 70에서 80
name : Jac, avg : 70

data : 80에서 90
name : Max, avg : 80

 

📌 join(inner join)

- 두 개의 데이터를 연결하는 키워드

// C#

 class Program
    {
        struct Student
        {
            public int _id;
            public string _name;
            public int _kor;
            public int _eng;

            public Student(int _id, string _name, int _kor, int _eng)
            {
                this._id = _id;
                this._name = _name;
                this._kor = _kor;
                this._eng = _eng;
            }
        }

        struct Detail
        {
            public string _name;
            public int _gender;
        }
        static void Main(string[] args)
        {
            Student[] arrStudents =
            {
                new Student(){_id = 100, _name = "John", _kor = 100, _eng = 20},
                new Student(){_id = 200, _name = "Jane", _kor = 80, _eng = 20},
                new Student(300, "Tom", 50, 60),
                new Student(400, "Max", 80, 80),
                new Student(500, "Jack", 70, 70)
            };
            Detail[] arrDetails =
            {
                // Tom은 Details에 없음
                new Detail(){ _name = "John", _gender = 1},
                new Detail(){ _name = "Jane", _gender = 0},
                new Detail(){ _name = "Juliet", _gender = 0},
                new Detail(){ _name = "Max", _gender = 1},
                new Detail(){ _name = "Jack", _gender = 1},
            };

            var QueryData =
                from data in arrStudents
                // 두 데이터의 _name을 기준으로 연결
                join detail in arrDetails on data._name equals detail._name
                select new
                {
                    name = data._name,
                    total = data._kor + data._eng,
                    gender = (detail._gender == 0) ? "여자" : "남자"
                };

            foreach (var data in QueryData)
            {
                Console.WriteLine("name : " + data.name);
                Console.WriteLine("total : " + data.total);
                Console.WriteLine("gender : " + data.gender);
                Console.WriteLine();
            }
        }
    }

// Tom은 포함되지 않음
Output:
name : John
total : 120
gender : 남자

name : Jane
total : 100
gender : 여자

name : Max
total : 160
gender : 남자

name : Jack
total : 140
gender : 남자

 

📌 join(outter join)

- 두 개의 데이터를 연결하는 키워드

// C#


            var QueryData =
                from data in arrStudents
                // 찾고자하는 데이터가 없을 경우 inData로
                join detail in arrDetails on data._name equals detail._name into inData
                //inData가 비어있지 않으면  _gender의 값을 1로 설정하고 detail로
                from detail in inData.DefaultIfEmpty(new Detail() { _gender = 1})
                select new
                {
                    name = data._name,
                    total = data._kor + data._eng,
                    gender = (detail._gender == 0) ? "여자" : "남자"
                };

            foreach (var data in QueryData)
            {
                Console.WriteLine("name : " + data.name);
                Console.WriteLine("total : " + data.total);
                Console.WriteLine("gender : " + data.gender);
                Console.WriteLine();
            }

// Tom 포함
Output:
name : John
total : 120
gender : 남자

name : Jane
total : 100
gender : 여자

name : Tom
total : 110
gender : 남자

name : Max
total : 160
gender : 남자

name : Jack
total : 140
gender : 남자

 

📌 LINQ의 장점

- SQL 문법과 유사하기 때문에 SQL 사용이 익숙하다면 쉽게 사용이 가능하다.

- LINQ는 컴파일 시간에 타입을 체크하기 때문에 프로그램 실행 전에 문제가 되는 코드를 수정할 수 있다.

- 반복문 또는 조건문을 사용하는 것보다 코드가 간결해진다.

- LINQ의 쿼리는 재사용이 가능하다.

📌 LINQ의 단점

- SQL을 사용해 보지 못한 개발자들에게는 어려울 수 있다.

- SQL과 유사하지만, 복잡한 쿼리는 작성할 수 없다.

- 쿼리가 잘못 작성될 경우 반복문을 사용하는 것보다 성능이 저하될 수 있다.

profile
복습하기 위해 쓰는 글

0개의 댓글