일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- navigation
- Unity
- unity git
- m590 수리
- 유니티 머지
- Github DeskTop Merge
- NavMesh
- unity merge
- networkobject.networkid
- nav오브젝트사이거리
- networkbehaviourid
- M590
- unity 병합
- 유니티
- 유니티 해상도 설정
- 깃허브 데스크탑 병합
- 유니티 해상도 변경
- 깃허브 데스크탑 합치기
- githubdesktopmerge
- nav거리
- 유니티 해상도
- 오브젝트 깜빡임
- networkobject
- m585 수리
- stateauthority
- m585
- 유니티 합치기
- 유니티 브랜치 merge
- 몬스터
- Today
- Total
집게사장의 꿈
C# LINQ 쿼리 키워드 본문
https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/query-keywords
From
"데이터 소스 참조할 변수를 지정하는 것"
기본
var lowNums = from num in numbers
where num < 5
select num;
num : int 타입 참조받을 데이터
numbers : 참조할 데이터 컬렉션
복합 From
List<Student> students =
[
new Student {LastName="Omelchenko", Scores= [97, 72, 81, 60]},
new Student {LastName="O'Donnell", Scores= [75, 84, 91, 39]},
new Student {LastName="Mortensen", Scores= [88, 94, 65, 85]},
new Student {LastName="Garcia", Scores= [97, 89, 85, 82]},
new Student {LastName="Beebe", Scores= [35, 72, 91, 70]}
];
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };
설명 : strudents에 있는 Scores 배열값을 참조하기 위한 것
From Join
'For 반복문을 사용한 결과와 같음'
char[] upperCase = ['A', 'B', 'C'];
char[] lowerCase = ['x', 'y', 'z'];
//Cross Join
var joinQuery1 =
from upper in upperCase
from lower in lowerCase
select new { upper, lower };
//Filtered non-equijoin
var joinQuery2 =
from lower in lowerCase
where lower != 'x'
from upper in upperCase
select new { lower, upper };
/* Output:
Cross join:
A is matched to x
A is matched to y
A is matched to z
B is matched to x
B is matched to y
B is matched to z
C is matched to x
C is matched to y
C is matched to z
Filtered non-equijoin:
y is matched to A
y is matched to B
y is matched to C
z is matched to A
z is matched to B
z is matched to C
*/
Where
"데이터 소스에서 어떠한 요소가 쿼리식에 반환될지를 정하는 것"
'Bool 조건을 적용하여 반환될 요소를 지정할 수 있다.'
기본
//5보다 작은 값을 찾아서 반환
var queryLowNums =
from num in numbers
where num < 5
select num;
Where 중첩
//&& || 연산을 사용
var queryLowNums2 =
from num in numbers
where num < 5 && num % 2 == 0
select num;
//Where을 중첩
var queryLowNums3 =
from num in numbers
where num < 5
where num % 2 == 0
select num;
// Output:
// 4 2 0
// 4 2 0
instance || static 함수를 사용한 Where연산
var queryEvenNums =
from num in numbers
where IsEven(num)
select num;
// Method may be instance method or static method.
static bool IsEven(int i) => i % 2 == 0;
Select
"값이 생성되는 형식을 지정하는 것"
기본
//score을 그래도 사용하는 것
IEnumerable<int> queryHighScores =
from score in Scores
where score > 80
select score;
복합
///클래스 --------------------
public class Student
{
public required string First { get; init; }
public required string Last { get; init; }
public required int ID { get; init; }
public required List<int> Scores;
public ContactInfo? GetContactInfo(SelectSample2 app, int id)
{
ContactInfo? cInfo =
(from ci in app.contactList
where ci.ID == id
select ci)
.FirstOrDefault();
return cInfo;
}
public override string ToString() => $"{First} {Last}:{ID}";
}
public class ContactInfo
{
public required int ID { get; init; }
public required string Email { get; init; }
public required string Phone { get; init; }
public override string ToString() => $"{Email},{Phone}";
}
///데이터 ---------------------------------
List<Student> students =
[
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int>() {97, 92, 81, 60}},
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int>() {75, 84, 91, 39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int>() {88, 94, 65, 91}},
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int>() {97, 89, 85, 82}},
];
// Separate data source for contact info.
List<ContactInfo> contactList =
[
new ContactInfo {ID=111, Email="SvetlanO@Contoso.com", Phone="206-555-0108"},
new ContactInfo {ID=112, Email="ClaireO@Contoso.com", Phone="206-555-0298"},
new ContactInfo {ID=113, Email="SvenMort@Contoso.com", Phone="206-555-1130"},
new ContactInfo {ID=114, Email="CesarGar@Contoso.com", Phone="206-555-0521"}
];
/// 쿼리---------------------------------
//Student 클래스에서 ContactInfo클래스를 반환받아 데이터를 선택
IEnumerable<ContactInfo> studentQuery3 =
from student in app.students
where student.ID > 111
select student.GetContactInfo(app, student.ID);
//새로운 ScoreInfo 쿨래스 생성
IEnumerable<ScoreInfo> studentQuery8 =
from student in app.students
where student.ID > 111
select new ScoreInfo
{
Average = student.Scores.Average(),
ID = student.ID
};
//임시 데이터 타입을 생성
var studentQuery7 =
from student in app.students
where student.ID > 111
select new { student.First, student.Last };
//Join 연산을 사용 후 데이터를 선택
IEnumerable<ContactInfo> studentQuery9 =
from student in app.students
where student.Scores.Average() > 85
join ci in app.contactList on student.ID equals ci.ID
select ci;
Group
"그룹의 키 값과 일치하는 0개 이상의 항목으로 그룹화된 데이터를 반환하는 것"
반환 형식 : IGrouping<TKey,TElement>
기본
// Query variable is an IEnumerable<IGrouping<char, Student>>
var studentQuery1 =
from student in students
group student by student.Last[0];
group : 그룹을 만들 데이터
by : 그룹의 분류가 될 키값
참조 방법
foreach (IGrouping<char, Student> studentGroup in studentQuery2)
{
Console.WriteLine(studentGroup.Key);
// Explicit type for student could also be used here.
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}", student.Last, student.First);
}
}
into
var studentQuery2 =
from student in students
group student by student.Last[0] into g
orderby g.Key
select g;
그룹화된 내용을 g라는 이름으로 임시 식별자로 지정한다.
Bool로 구분한 그룹
//Bool 값을 사용한 그룹화
var booleanGroupQuery =
from student in students
group student by student.Scores.Average() >= 80; //pass or fail!
숫자 범위에 따른 그룹화
var studentQuery =
from student in students
let avg = (int)student.Scores.Average()
group student by (avg / 10) into g
orderby g.Key
select g;
OrderBy
"시퀀스 또는 하위 시퀀스(그룹)가 오름차순 또는 내림차순으로 정렬"
기본
//오름차순
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //"ascending" is default
select fruit;
// 내림차순
IEnumerable<string> sortDescendingQuery =
from w in fruits
orderby w descending
select w;
Let
"쿼리 하위식에 대한 값을 저장하여 사용할 때"
기본
string[] strings =
[
"A penny saved is a penny earned.",
"The early bird catches the worm.",
"The pen is mightier than the sword."
];
// Split the sentence into an array of words
// and select those whose first letter is a vowel.
var earlyBirdQuery =
from sentence in strings
let words = sentence.Split(' ')
from word in words
let w = word.ToLower()
where w[0] == 'a' || w[0] == 'e'
|| w[0] == 'i' || w[0] == 'o'
|| w[0] == 'u'
select word;
// Execute the query.
foreach (var v in earlyBirdQuery)
{
Console.WriteLine("\"{0}\" starts with a vowel", v);
}
Join
"두 개의 소스 시퀀스를 이용하여 연결하는 것"
[예를 들어 ]
join 절은 모두 동일한 지역에 있는, 해당 제품의 공급업체 및 구매자 목록을 만드는 데 사용
join 절은 특수한 equals 키워드를 사용하여 지정된 키가 같은지 비교
join 절로 수행된 모든 조인은 동등 조인
데이터 정의
List<Category> categories =
[
new Category {Name="Beverages", ID=001},
new Category {Name="Condiments", ID=002},
new Category {Name="Vegetables", ID=003},
new Category {Name="Grains", ID=004},
new Category {Name="Fruit", ID=005}
];
// Specify the second data source.
List<Product> products =
[
new Product {Name="Cola", CategoryID=001},
new Product {Name="Tea", CategoryID=001},
new Product {Name="Mustard", CategoryID=002},
new Product {Name="Pickles", CategoryID=002},
new Product {Name="Carrots", CategoryID=003},
new Product {Name="Bok Choy", CategoryID=003},
new Product {Name="Peaches", CategoryID=005},
new Product {Name="Melons", CategoryID=005},
];
내부 조인
같은 ID에 해당하는 모든 경우의 수를 탐색 후 조합하는 것과 동일
for문을 돌려 category.ID와 prod.CategoryID가 동일하다면 해당 카테고리 아이디와 음료 이름을 조합하는 것이라고 생각해도 좋다.
var innerJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID
select new { Category = category.ID, Product = prod.Name };
Console.WriteLine("InnerJoin:");
// Execute the query. Access results
// with a simple foreach statement.
foreach (var item in innerJoinQuery)
{
Console.WriteLine("{0,-10}{1}", item.Product, item.Category);
}
Console.WriteLine("InnerJoin: {0} items in 1 group.", innerJoinQuery.Count());
Console.WriteLine(System.Environment.NewLine);
/*
InnerJoin:
Cola 1
Tea 1
Mustard 2
Pickles 2
Carrots 3
Bok Choy 3
Peaches 5
Melons 5
InnerJoin: 8 items in 1 group.
*/
prod : products 데이터를 참조받아올 데이터
products : 원본 데이터 소스
on : 조건
equals : 좌 우 데이터가 동일한지 판단
그룹 조인
왼쪽 소스 시퀀스의 요소를 오른쪽 소스 시퀀스에서 일치하는 하나 이상의 요소와 연결하는 계층적 결과 시퀀스를 생성
일치하는 항목이 없을 경우 join 절은 해당 항목에 대해 빈 배열을 생성
따라서 결과 시퀀스가 그룹으로 구성된다는 점을 제외하면 그룹 조인은 기본적으로 내부 동등 조인
//category.ID equals prod.CategoryID 통해 생성된 join은 하나의 그룹이 되며,
//prod가 그룹 내부 요소로 지정된다.
var groupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select prodGroup;
// Store the count of total items (for demonstration only).
int totalItems = 0;
Console.WriteLine("Simple GroupJoin:");
//그룹 아이템은 products를 기준
foreach (var prodGrouping in groupJoinQuery)
{
Console.WriteLine("Group:");
foreach (var item in prodGrouping)
{
totalItems++;
Console.WriteLine(" {0,-10}{1}", item.Name, item.CategoryID);
}
}
/*
Unshaped GroupJoin:
Group:
Cola 1
Tea 1
Group:
Mustard 2
Pickles 2
Group:
Carrots 3
Bok Choy 3
Group:
Group:
Peaches 5
Melons 5
Unshaped GroupJoin: 8 items in 5 unnamed groups
*/
그룹 내부 조인
//prod 로 그룹화된 내용을 재정의
var groupJoinQuery2 =
from category in categories
orderby category.ID
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new
{
Category = category.Name,
Products = from prod2 in prodGroup
orderby prod2.Name
select prod2
};
//Console.WriteLine("GroupInnerJoin:");
int totalItems = 0;
Console.WriteLine("GroupInnerJoin:");
foreach (var productGroup in groupJoinQuery2)
{
Console.WriteLine(productGroup.Category);
foreach (var prodItem in productGroup.Products)
{
totalItems++;
Console.WriteLine(" {0,-10} {1}", prodItem.Name, prodItem.CategoryID);
}
}
/*
GroupInnerJoin:
Beverages
Cola 1
Tea 1
Condiments
Mustard 2
Pickles 2
Vegetables
Bok Choy 3
Carrots 3
Grains
Fruit
Melons 5
Peaches 5
GroupInnerJoin: 8 items in 5 named groups
*/
그룹 내부 조인 2
var groupJoinQuery3 =
from category in categories
join product in products on category.ID equals product.CategoryID into prodGroup
from prod in prodGroup
orderby prod.CategoryID
select new { Category = prod.CategoryID, ProductName = prod.Name };
왼쪽 우선 외부 조인
오른쪽 시퀀스에 일치하는 요소가 없는 경우에도 왼쪽 소스 시퀀스의 모든 요소가 반환된다.
왼쪽 우선 외부 조인을 실행하려면 그룹조인과 함께, DefaultIfEmpty 메서드를 사용하여 왼쪽 요소에 일치하는 없을 경우 생성할 기본 오른쪽 요소를 지정
//category.ID equals prod.CategoryID로 일치하는 prod가 없으면 빈 배열이 반환되는데,
//만약 빈 배열인 경우의 기본값을 지정해주는 것
var leftOuterQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select prodGroup.DefaultIfEmpty(new Product() { Name = "Nothing!", CategoryID = category.ID });
// Store the count of total items (for demonstration only).
int totalItems = 0;
Console.WriteLine("Left Outer Join:");
// A nested foreach statement is required to access group items
foreach (var prodGrouping in leftOuterQuery)
{
Console.WriteLine("Group:");
foreach (var item in prodGrouping)
{
totalItems++;
Console.WriteLine(" {0,-10}{1}", item.Name, item.CategoryID);
}
}
왼쪽 우선 외부 조인 2
//DefaultIfEmpty()에 기본값이 없기에 빈 배열일 경우 Null이 반환
var leftOuterQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from item in prodGroup.DefaultIfEmpty()
select new { Name = item == null ? "Nothing!" : item.Name, CategoryID = category.ID };
Console.WriteLine("LeftOuterJoin2: {0} items in 1 group", leftOuterQuery2.Count());
// Store the count of total items
int totalItems = 0;
Console.WriteLine("Left Outer Join 2:");
// Groups have been flattened.
foreach (var item in leftOuterQuery2)
{
totalItems++;
Console.WriteLine("{0,-10}{1}", item.Name, item.CategoryID);
}
출처
https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/query-keywords
'기타 > C#' 카테고리의 다른 글
LINQ 집합 (0) | 2024.07.23 |
---|---|
LINQ 집계함수 (0) | 2024.07.23 |
LINQ 메서드 GroupBy (1) | 2024.07.23 |
LINQ 메서드 (0) | 2024.07.23 |
C# LINQ 소개 (0) | 2024.07.21 |