C# LinQ 쿼리 사용방법

야민·2023년 3월 16일

LinQ 란?

LINQ(Language Integrated Query)는 C#과 같은 .NET 언어에서 데이터 소스와 상호 작용하는 간편한 방법을 제공하는 통합 쿼리 기능입니다. LINQ를 사용하면 C# 코드에서 데이터베이스 쿼리와 유사한 방식으로 데이터 소스에서 쿼리를 실행할 수 있습니다.

LINQ 쿼리의 동작 방식

  1. 데이터 소스: 쿼리할 데이터가 저장된 데이터 소스를 지정합니다. 예를 들어, 배열, 리스트, 컬렉션, 데이터베이스 테이블, Json Object 등을 데이터 소스로 사용할 수 있습니다.

  2. 쿼리 만들기: LINQ에서 쿼리는 일반적으로 '확장 메서드'와 '쿼리 식'으로 만듭니다. 쿼리 식은 SQL 쿼리와 유사한 구문을 사용하여 쉽게 작성할 수 있습니다. 예를 들어, SELECT, FROM, WHERE, ORDER BY 등과 같은 구문이 사용됩니다.

  3. 결과 처리: 쿼리 결과를 처리하여 필요한 작업을 수행합니다. 예를 들어, 데이터를 검색하거나, 정렬하거나, 필터링하거나, 그룹화하거나, 변환하거나, 집계하거나 등의 작업을 수행할 수 있습니다.
    반환타입 IEtermable

LINQ 쿼리에서 가장 자주 사용되는 예약어

  • from: 데이터 소스에서 가져올 요소를 지정합니다.
  • where: 데이터를 필터링합니다.
  • orderby: 데이터를 정렬합니다. - de, as
  • select: 데이터를 반환합니다.
  • group by: 데이터를 그룹화합니다.
  • join: 두 개의 데이터 소스를 결합합니다.
  • let: 임시 변수를 만들어 쿼리 내에서 사용합니다.

Select 예약어

반환타입을 지정

var users = from u in jsonObj["users"]
            where (string)u["name"] == "John"
            // 반환 타입을 해당 목록 아이템의 내부 변수로 지정 가능
            select u["name"];

// 원하는 데이터만 추가하여 반환 가능 - 문명형식; 값 내부 수식 사용 가능
var users = from u in jsonObj["users"]
            where (string)u["name"] == "John"
            select new {
            	name: u["name"],
                type: u["type"],
                data: (u["data"] as int) * 0.5,
            };
            

from 예약어

이중 from 사용 가능

var users = from u in jsonObj["users"]
				from game in u.favGame
            	where (int)game["like"] > 100
            select u;
            

배열에서의 사용

int[] numbers = { 1, 2, 3, 4, 5 };
var query = from number in numbers
            where number > 2
            select number * 2;

위 예시에서는 배열 numbers에서 값이 2보다 큰 수를 선택하고, 선택한 수에 2를 곱한 값을 query 변수에 저장합니다.

Json Object에서의 사용

using Newtonsoft.Json.Linq;
// JSON 데이터 예시
string jsonData = @"
{
  'users': [
    {
      'name': 'John',
      'age': 30,
      'email': 'john@example.com'
    },
    {
      'name': 'Jane',
      'age': 25,
      'email': 'jane@example.com'
    },
    {
      'name': 'Bob',
      'age': 40,
      'email': 'bob@example.com'
    }
  ]
}";
// JObject로 변환
JObject jsonObj = JObject.Parse(jsonData);
// LINQ 쿼리로 검색
var users = from u in jsonObj["users"]
            where (string)u["name"] == "John"
            select u;
// 결과 출력
foreach (var user in users)
{
    Console.WriteLine(user["name"] + " " + user["email"]);
}

위 예시에서는 JObject.Parse를 사용하여 JSON 데이터를 JObject로 변환하고, LINQ 쿼리를 사용하여 이름이 "John"인 사용자를 검색합니다.

확장 메서드와 쿼리식의 형태 차이

var result = jsonData.Where(j => j["name"].ToString().Contains("John"));

여기서 j는 JObject 인스턴스를 나타내고, ToString() 메소드를 사용하여 해당 필드의 값을 문자열로 변환합니다. 그런 다음 Contains 메소드를 사용하여 필드의 문자열 값이 "John"을 포함하는지 확인합니다. 이 쿼리는 "John"이 포함된 "John Doe"나 "Johnny" 등의 모든 이름을 검색합니다.

또한 StartsWith 또는 EndsWith 메소드를 사용하여 필드의 문자열 값이 특정 문자열로 시작하는지 또는 끝나는지 확인할 수도 있습니다. 이러한 메소드는 Contains 메소드와 함께 조합하여 더 복잡한 검색 쿼리를 작성하는 데 사용될 수 있습니다.

정렬 쿼리

int[] numbers = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 };
var sortedNumbers = from num in numbers
                    orderby num ascending // ascending (오름차순)으로 정렬
                    select num;
foreach (var num in sortedNumbers)
{
    Console.WriteLine(num);
}

위 코드는 numbers 배열을 orderby 키워드를 사용하여 오름차순으로 정렬하고 있습니다. 출력 결과는 다음과 같습니다.

깊은 Json Object에서의 데이터 쿼리 예시

using System;
using System.Linq;
using Newtonsoft.Json.Linq;

namespace JsonQueryExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string jsonData = @"{
                ""members"": [
                    {
                        ""name"": ""Alice"",
                        ""age"": 25,
                        ""address"": {
                            ""city"": ""New York"",
                            ""state"": ""NY""
                        }
                    },
                    {
                        ""name"": ""Bob"",
                        ""age"": 30,
                        ""address"": {
                            ""city"": ""Los Angeles"",
                            ""state"": ""CA""
                        }
                    },
                    {
                        ""name"": ""Charlie"",
                        ""age"": 20,
                        ""address"": {
                            ""city"": ""Chicago"",
                            ""state"": ""IL""
                        }
                    }
                ]
            }";

            JObject json = JObject.Parse(jsonData);
            var members = json["members"].Where(m => m["name"].ToString() == "Bob");
            foreach (var member in members)
            {
                Console.WriteLine("Name: {0}, Age: {1}, City: {2}, State: {3}",
                    member["name"], member["age"], member["address"]["city"], member["address"]["state"]);
            }
        }
    }
}

json을 문자열로 작성하여 파싱할 경우 매우 엄갹한 문법 검사가 이루어 진다.
아래 방법을 사용해서 코드 작성시에 json 데이터를 입력하고 사용할 수 있다.

C#에서 json 변수를 jsonEncode 및 Decode 하는 빙접

dynamic jsonData = new
{
    name = "John Doe",
    age = 30,
    email = "john.doe@example.com"
};

string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(jsonData);
JObject jsonObject = JObject.Parse(jsonString);

확장 메서드와 쿼리식의 차이

from u in users where ... 구문은 쿼리식 구문으로, SQL 쿼리와 비슷한 구조를 가지며, 데이터 소스(users), 범위 변수(u) 및 조건(where)을 포함합니다.
jsonData.Where(...) 메서드는 메서드 구문으로, LINQ 확장 메서드를 사용하여 쿼리를 작성합니다. 이 메서드는 IEnumerable 또는 IQueryable 타입의 데이터 소스에서 쿼리를 수행하는데 사용됩니다. 메서드 구문은 from ... in ... where ... select ... 구문과 비슷한 역할을 수행하지만, 각 구문 요소가 개별 메서드로 작성됩니다.
두 구문 모두 LINQ 쿼리를 작성하는 방법 중 하나이며, 어떤 구문을 선택하느냐는 개발자의 취향이나 상황에 따라 다릅니다.

NoSql 형태의 데이터베이스를 쿼리할 때는 구글의 Firestore의 쿼리방식과 비슷하다

0개의 댓글