목차
C#의 LINQ 쿼리 식은 특별한 문법을 사용하여 데이터 소스에서 데이터를 쿼리하는 데 사용됩니다. 쿼리 식은 일반적으로 SQL과 비슷한 구문을 제공하여 데이터를 검색, 필터링 및 변환하는 데 편리합니다. 아래는 쿼리 식의 기본 사항에 대한 자세한 설명입니다:
기본
from 절:
from 절은 데이터 소스에서 데이터를 가져오는 역할을 합니다. 데이터 소스의 각 요소를 대상 범위 변수에 할당하여 사용할 수 있도록 합니다.
from 변수 in 데이터소스
쿼리 변수 및 범위 변수:
from 절에서 선언된 변수는 쿼리 변수입니다.
이 변수는 쿼리 식 내에서 사용되며 데이터 소스의 각 요소에 대한 반복을 나타냅니다.
where, select 절에서 사용되는 변수는 범위 변수로, from 절에서 선언된 쿼리 변수를 참조합니다.
from num in numbers
where num % 2 == 0
select num
위의 예제에서 num은 쿼리 변수이고, where와 select 절에서 사용됩니다.
여러 from 절:
여러 데이터 소스에서 데이터를 결합하기 위해 여러 from 절을 사용할 수 있습니다.
from x in numbers
from y in numbers
where x * y > 5
select new { X = x, Y = y, Product = x * y }
위의 예제에서 x와 y는 각각의 데이터 소스에 대한 범위 변수입니다.
쿼리 식 종료
쿼리 식은 group 절 또는 select 절로 끝나야 합니다.
group 절
var queryCountryGroups =
from country in countries
group country by country.Name[0];
다양한 예제.
public class Country
{
public string Name { get; set; }
public List<City> Cities { get; set; }
public int Population { get; set; }
}
public class City
{
public string Name { get; set; }
public int Population { get; set; }
}
// 국가 및 도시 데이터 생성
List<Country> countries = new List<Country>
{
new Country
{
Name = "USA",
Cities = new List<City>
{
new City { Name = "New York", Population = 8000000 },
new City { Name = "Los Angeles", Population = 4000000 }
// 추가 도시 정보
}
},
new Country
{
Name = "USA",
Cities = new List<City>
{
new City { Name = "Chicago", Population = 8000000 },
new City { Name = "Houston", Population = 4000000 }
// 추가 도시 정보
}
},
new Country
{
Name = "KOR",
Cities = new List<City>
{
new City { Name = "Seoul ", Population = 8000000 },
new City { Name = "Daegu", Population = 4000000 }
// 추가 도시 정보
}
},
// 추가 국가 정보
};
// 방법 1 국가코드 앞글자만 Key로 사용
var queryCountryGroups =
from country in countries
group country by country.Name[0];
foreach (var group in queryCountryGroups)
{
Debug.Log($"Countries with first letter '{group.Key}':");
foreach (var country in group)
{
Debug.Log($" {country.Name}");
}
}
Debug.Log($"");
// 방법2 국가코드를 Key로 사용
var countries1 = from country in countries
group country by country.Name;
foreach (var group in countries1)
{
Debug.Log($"Countries with first letter '{group.Key}':");
foreach (var country in group)
{
Debug.Log($" {country.Name}");
}
}
Debug.Log($"");
// 방법3 Key는 국가, Value는 City로
var queryCountryGroups2 =
from country in countries
from city in country.Cities
group city by country.Name[0];
// LOG queryCountryGroups2
foreach (var group in queryCountryGroups2)
{
Debug.Log($"Countries with first letter '{group.Key}':");
foreach (var city in group)
{
Debug.Log($" {city.Name}");
}
}
select 절
IEnumerable<Country> sortedQuery =
from country in countries
orderby country.Area
select country;
var queryNameAndPop =
from country in countries
select new
{
Name = country.Name,
Pop = country.Population
};
into를 사용한 연속
// percentileQuery is an IEnumerable<IGrouping<int, Country>>
var percentileQuery =
from country in countries
let percentile = (int)country.Population / 10_000_000
group country by percentile into countryGroup
where countryGroup.Key >= 20
orderby countryGroup.Key
select countryGroup;
// grouping is an IGrouping<int, Country>
foreach (var grouping in percentileQuery)
{
Console.WriteLine(grouping.Key);
foreach (var country in grouping)
{
Console.WriteLine(country.Name + ":" + country.Population);
}
}
필터링, 정렬 및 조인
where 절
IEnumerable<City> queryCityPop =
from city in cities
where city.Population is < 200000 and > 100000
select city;
orderby 절
Area는 오름차순정렬. Area 이 같다면 Population 내림차순
IEnumerable<Country> querySortedCountries =
from country in countries
orderby country.Area, country.Population descending
select country;
Area는 오름차순정렬. Area 이 같다면 Population 오름차순정렬
IEnumerable<Country> querySortedCountries =
from country in countries
orderby country.Area ascending, country.Population ascending
select country;
join 절
결합하고 새로운걸 만들수 있음.
// 가상의 클래스 정의
class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
}
public void OnClick_join()
{
// 가상의 데이터 클래스 정의
List<Category> categories = new List<Category>
{
new Category { Id = 1, Name = "Electronics" },
new Category { Id = 2, Name = "Clothing" },
// 추가적인 카테고리들...
};
List<Product> products = new List<Product>
{
new Product { Id = 101, Name = "Laptop", Category = "Electronics" },
new Product { Id = 102, Name = "Smartphone", Category = "Electronics" },
new Product { Id = 201, Name = "T-Shirt", Category = "Clothing" },
// 추가적인 제품들...
};
// LINQ 쿼리
var categoryQuery =
from cat in categories
join prod in products on cat.Name equals prod.Category
select new
{
Category = cat.Name,
ProductName = prod.Name,
createTestID = cat.Id,
};
// 결과 출력
foreach (var result in categoryQuery)
{
Console.WriteLine($"Category: {result.Category}, Product: {result.ProductName}");
}
}
let 절
string[] names = ["Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia"];
IEnumerable<string> queryFirstNames =
from name in names
let firstName = name.Split(' ')[0]
select firstName;
foreach (var s in queryFirstNames)
{
Console.Write(s + " ");
}
//Output: Svetlana Claire Sven Cesar
쿼리 식의 하위 쿼리
var queryGroupMax =
from student in students
group student by student.Year into studentGroup
select new
{
Level = studentGroup.Key,
HighestScore = (
from student2 in studentGroup
select student2.ExamScores.Average()
).Max()
};
쿼리 식의 종류:
쿼리 식은 쿼리 식 구문과 메서드 구문 두 가지 형식으로 사용할 수 있습니다. 쿼리 식 구문은 SQL과 유사한 구문을 사용하며, 메서드 구문은 메서드 체이닝을 통해 쿼리를 작성하는 방식입니다.
// 쿼리 식 구문
var result = from num in numbers
where num % 2 == 0
select num;
// 메서드 구문
var result = numbers.Where(num => num % 2 == 0);
두 가지 형식은 기능적으로 동일하며, 개발자는 편한 방식을 선택하여 사용할 수 있습니다.
쿼리 식은 데이터를 효과적으로 검색하고 조작하는 강력한 도구로, LINQ의 주요 특징 중 하나입니다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int[] scores = { 90, 71, 82, 93, 75, 82 };
// 개별 요소를 수정하지 않고 요소의 하위 집합을 검색하여 새 시퀀스를 생성합니다.
// 쿼리는 다음 예제와 같이 반환된 시퀀스를 다양한 방법으로 정렬하거나 그룹화할 수 있습니다(가정 scores 은 다음과 같습니다. int[]).
IEnumerable<int> highScoresQuery =
from score in scores
where score > 80
orderby score descending
select score;
highScoresQuery.ToList().ForEach(score => Debug.Log(score));
// 다음 예제는 int에서 string으로의 프로젝션을 보여 줍니다. highScoresQuery의 새 형식을 참조하세요.
IEnumerable<string> highScoresQuery2 =
from score in scores
where score > 80
orderby score descending
select $"The score is {score}";
highScoresQuery2.ToList().ForEach(score => Debug.Log(score));
// 조건과 일치하는 첫 번째 요소 또는 지정된 요소 집합에서 특정 값의 합계. 예를 들어 다음 쿼리는 scores 정수 배열에서 80보다 큰 점수를 반환
var highScoreCount = (
from score in scores
where score > 80
select score
).Count();
Debug.Log(highScoreCount);
// 이전 예제에서는 Enumerable.Count 메서드를 호출하기 전에 쿼리 식 주변에 괄호를 사용했습니다.
// 새 변수를 사용하여 구체적인 결과를 저장할 수도 있습니다.
IEnumerable<int> highScoresQuery3 =
from score in scores
where score > 80
select score;
var scoreCount = highScoresQuery3.Count();
Debug.Log(scoreCount);
////////////////////////////////////////
쿼리 변수
- LINQ에서 쿼리 변수는 쿼리의 결과 대신 쿼리를 저장하는 변수\
- 하나의 데이터 소스, 하나의 필터링 절, 하나의 순서 지정 절, 변환 없는 원본 요소로 간단한 쿼리 식을 보여 줍니다. select 절은 쿼리를 종료
// Data source.
int[] scores = {90, 71, 82, 93, 75, 82};
// Query Expression.
IEnumerable<int> scoreQuery = //query variable
from score in scores //required
where score > 80 // optional
orderby score descending // optional
select score; //must end with select or group
// Execute the query to produce the results
foreach (var testScore in scoreQuery)
{
Console.WriteLine(testScore);
}
- 위 코드애서 Foreach 할때 실제 데이터가 저장. 지연된다.
- 두 예제는 쿼리를 사용하여 초기화 하고. 변수를 보여준다. 결과를 저장하기 때문에 쿼리 변수가 아니다
var highestScore = (
from score in scores
select score
).Max();
// or split the expression
IEnumerable<int> scoreQuery =
from score in scores
select score;
var highScore = scoreQuery.Max();
// the following returns the same result
highScore = scores.Max();
var largeCitiesList = (
from country in countries
from city in country.Cities
where city.Population > 10000
select city
).ToList();
// or split the expression
IEnumerable<City> largeCitiesQuery =
from country in countries
from city in country.Cities
where city.Population > 10000
select city;
var largeCitiesList2 = largeCitiesQuery.ToList();
'C# > LINQ' 카테고리의 다른 글
표준 쿼리 연산자 : LINQ를 통한 데이터 변환(C#) (1) | 2024.01.04 |
---|---|
확장명 메서드 (0) | 2024.01.03 |
C# LINQ 쿼리를 작성하여 데이터 쿼리 (0) | 2024.01.01 |
LINQ 쿼리 소개(C#) (0) | 2023.12.30 |