공부/웹서버

LINQ

원클릭쓰리버그 2022. 4. 29. 20:30
728x90

LINQ는 유니티에서는 권장하지 않는 문법이라서 공부 필요성을 느끼지 못했지만, 데이터와 웹서버에서 많이 다루는 문법이어서 공부를 하게 되었다.

 

LINQ

쿼리는 데이터 소스에서 데이터를 검색하는 식입니다. 쿼리는 일반적으로 특수화된 쿼리 언어로 표현됩니다. 관계형 데이터베이스에는 SQL이 사용되고 XML에는 XQuery가 사용되는 것처럼 시간에 따라 다양한 형식의 데이터 소스에 대해 서로 다른 언어가 개발되었습니다. 따라서 개발자는 지원해야 하는 데이터 소스의 형식이나 데이터 형식에 따라 새로운 쿼리 언어를 배워야 했습니다. LINQ는 다양한 데이터 소스 및 형식에 사용할 수 있는 일관된 모델을 제공함으로써 이러한 상황을 단순화합니다. LINQ 쿼리에서는 항상 개체를 사용합니다. XML 문서, SQL 데이터베이스, ADO.NET 데이터 세트, .NET 컬렉션 및 LINQ 공급자를 사용할 수 있는 다른 모든 형식에서 데이터를 쿼리하고 변환하는 데 동일한 기본 코딩 패턴을 사용합니다.

 

 

예시

 

플레이어 생성 및 설정

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApp1
{
    //LINQ
    //데이터 및 웹서버에서 많이 다루는 문법
    public enum ClassType
    {
        Knight,
        Archer,
        Mage,
    }

    public class Player
    {
        public ClassType ClassType;
        public int Level;
        public int Hp;
        public int Attack;
        public List<int> Items { get; set; } = new List<int>();
    }
    
    class Program
    {
        static List<Player> _players = new List<Player>();
        static void Main(string[] args)
        {
            Random rand = new Random();

            // 플레이어 생성
            for (int i = 0; i < 100; i++)
            {
                ClassType type = ClassType.Knight;
                switch (rand.Next(0, 3))
                {
                    case 0:
                        type = ClassType.Knight;
                        break;
                    case 1:
                        type = ClassType.Archer;
                        break;
                    case 2:
                        type = ClassType.Mage;
                        break;
                }

                Player player = new Player()
                {
                    ClassType = type,
                    Level = rand.Next(1, 100),
                    Hp = rand.Next(100, 1000),
                    Attack = rand.Next(5, 50)
                };

                for (int k = 0; k < 5; k++)
                {
                    player.Items.Add(rand.Next(1, 101));
                }
                _players.Add(player);
            }

        }
    }
}

 

 

 

만약 플레이어의 직업이 Knight이고, 레벨 51 이상인 데이터를 만들고 싶다면 C#의 문법에서 

static public List<Player> GetHighLevelKnights()
                {
                    List<Player> players = new List<Player>();

                    foreach (Player item in _players)
                    {
                        if (item.ClassType != ClassType.Knight)
                            continue;
                        if (item.Level < 50)
                            continue;

                        players.Add(item);
                    }
                    players.Sort((Lhs, Rhs) => { return Lhs.Level - Rhs.Level; });
                    return players;
                }

하나하나 수행해야하는 함수를 만들어야 할 것이다. 또한, 프로그래머의 스타일에 따라 문법은 달라지게 된다. 

 

 

하지만 LINQ의 문법을 사용하게 된다면

using System.Linq;


var players =
                        from p in _players
                        where p.ClassType == ClassType.Knight && p.Level >= 50
                        orderby p.Level
                        select p;

이렇게 깔끔한 코드가 나올 수 있다. 만약 부분적으로 추출하고 싶다면 

 

select new { Hp = p.Hp, Level = p.Level * 2 };

이렇게 간단한 문법으로 가독성을 높일 수 있다는 장점이 있다.

 

 

 

 

여러가지 LINQ의 문법에 대해 알아보자

중첩 From

                        var playerItems = from p in _players
                                          from i in p.Items
                                          where i < 30
                                          select new { p, i };
                        var li = playerItems.ToList();

 

grouping 그룹

                        var playerByLevel = from p in _players
                                            group p by p.Level into g
                                            orderby g.Key
                                            select new { g.Key, players = g };

 

Join (내부 조인), outer join (외부 조인)

                        List<int> levels = new List<int>() { 1, 5, 9 };

                        var playerlevels =
                                            from p in _players
                                            join l in levels
                                            on p.Level equals l
                                            select p;

 

만약 더 많은 LINQ의 기능을 알고 싶다면 

https://docs.microsoft.com/ko-kr/dotnet/api/system.linq.enumerable?view=net-6.0 

 

Enumerable 클래스 (System.Linq)

IEnumerable<T>을 구현하는 개체를 쿼리하기 위한 static(Visual Basic의 경우 Shared) 메서드 집합을 제공합니다.

docs.microsoft.com

를 참고하자.

 

LINQ의 버전은 위의 문법처럼 적을 수 있지만 더 유연하고, 다양한 LINQ 함수를 실행하기 위해서는 

 

                //LINQ 버전
                {
                    var players =
                        from p in _players
                        where p.ClassType == ClassType.Knight && p.Level >= 50
                        orderby p.Level ascending
                        select p;

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

밑의 방식으로 사용하게 된다면 다양한 기능을 사용할 수 있다. 또한, 대부분의 문법은 데이터베이스의 문법과 비슷하기 때문에 데이터베이스 문법을 알고 있다면 쓰는데 어려움은 없다.

'공부 > 웹서버' 카테고리의 다른 글

MVC  (0) 2022.05.14
Asp.net  (0) 2022.04.30
css의 기초  (0) 2022.04.04
HTML 기초 # List / Table  (0) 2022.03.29
HTML 기초 #1  (0) 2022.03.25