공부/인프런 - Rookiss

Part 6-3-3. 고급 C# 문법 : LINQ #2

셩잇님 2024. 8. 23. 14:57
반응형

 

 

🚀 고급 C# 문법

 

 지난 시간에는 고급 C# 문법 중 하나인 LINQ에 대해서 학습하였다. LINQ는 RDBMS의 SQL과 굉장히 유사한 것을 볼 수 있다. 지난 시간에는 LINQ의 기초적인 문법에 대해서 학습하였다면 이번 시간에는 GROUP BY, JOIN 등에 대해서 학습하도록 하자.

 


 

👑 LINQ

 

 C#에서의 이중 for문과 같이 LINQ에서도 이중 from을 통해 이중 반복문을 만들 수 있다. 먼저 이를 테스트하기 위해 플레이어 클래스에 아이템을 새롭게 추가하도록 하자. 이 후, 단순히 아이템은 id를 통해 관리한다고 가정하고 player의 아이템 데이터도 설정해주도록 하자. 

 

    public class Player
    {
        public ClassType ClassType { get; set; }
        public int Level { get; set; }
        public int Hp { get; set; }
        public int Attack { get; set; }
        public List<int> Items { get; set; } = new List<int>();
    }
    
    class LINQ
    {
        static List<Player> _players = new List<Player>();

        static void Main(string[] args)
        {
            Random rand = new Random();

            for (int i = 0; i < 100; i++)
            {
            	// 직업 선택 (생략)
                
                // 플레이어 생성 (생략)

        	// 아이템 설정
                for (int j = 0; j < 5; j++)
                {
                    player.Items.Add(rand.Next(1, 101));
                }

                _players.Add(player);
            }
        }
    }

 


 

중첩 from

 

 아이템 id가 30 미만인 데이터를 추출하기 위해서는 다음과 같이 사용 할 수 있다. 먼저 from을 통해 _players를 한번 차례대로 돌고, 이 후 p의 Items를 순회하며 where 조건에 맞는 데이터를 찾아 이를 리스트화(ToList)하면 해당 데이터를 추출할 수 있다.

 

            // LINQ 버전 (중첩 from)
            // ex) 아이템 목록을 추출 (아이템 Id < 30)
            {
                var playerItems = from p in _players
                                  from item in p.Items
                                  where item < 30
                                  select new { p, item };

                var li = playerItems.ToList();
            }

 

Group by

 

 sql에서의 group by도 링크로 구현되어 있다. 이는 아래와 같다.

 

            // LINQ 버전 (Group By)
            {
                var playersByLevel = from p in _players
                                     group p by p.Level into g
                                     orderby g.Key
                                     select new { g.Key, Players = g };
            }

 

Join

 

 마찬가지로 sql에서 사용하던 내부 조인, 외부 조인 모두 경우에 따라 편하게 작성하여 처리할 수 있다.

 

            // LINQ 버전 (Join - 내부 조인, outer 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;
            }

 

표준 연산자

 

 사실 링크는 현재까지 작성하던 버전이 있는 반면, 대리자(Predicate)를 통해 생성되는 방식이 있다. 다음은 현재까지 작성한 코드와 동일한 대리자 버전이다.

 

            // LINQ 표준 연산자
            {
                var players =
                    from p in _players
                    where p.ClassType == ClassType.Knight && p.Level >= 50
                    orderby p.Level
                    select p;

                var players2 = _players
                        .Where(p => p.ClassType == ClassType.Knight && p.Level >= 50)
                        .OrderBy(p => p.Level)
                        .Select(p => p);
            }

 

 위와 아래의 함수는 동일한 로직을 나타낸다. 다만, 세부적으로 무엇인가 많은 기능을 이용하고 싶다고 할 경우 대리자를 통해 생성되는 버전을 사용해야 한다. 왜냐하면 위의 문법 where ↔ Where이 서로 매칭이 되어있는 경우도 있지만, 그렇지 않은 경우도 있기 때문에 가급적 대리자를 통한 방식을 추천한다.

 


 

 현재 강의에서 링크의 모든 함수들을 다 다룰 수는 없으므로 필요에 따라 그때그때 아래 링크를 통해 구현된 함수를 찾아 사용하도록 하자.

 

https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable?view=net-8.0

 

Enumerable Class (System.Linq)

Provides a set of static (Shared in Visual Basic) methods for querying objects that implement IEnumerable<T>.

learn.microsoft.com

 

 마지막으로 데이터를 링크를 통해 다룰 경우 Entity Framework와 같은 경우 해당 DB와 연동이 되어 실제 DB에 있는 정보를 가져오는 기능까지 할 수 있다. 이를 통해 엔티티 프레임워크와의 연동 작업도 구현할 수 있는 것까지 추가적으로 알아두면 좋다. 😎

 

 

반응형