select 절(C# 참조)
쿼리 식에서 select
절은 쿼리를 실행할 때 생성되는 값의 형식을 지정합니다. 결과는 모든 이전 절의 평가와 select
절 자체의 모든 계산을 기반으로 합니다. 쿼리 식은 select
절이나 group 절로 끝나야 합니다.
다음 예제에서는 쿼리 식의 간단한 select
절을 보여 줍니다.
class SelectSample1
{
static void Main()
{
//Create the data source
List<int> Scores = [97, 92, 81, 60];
// Create the query.
IEnumerable<int> queryHighScores =
from score in Scores
where score > 80
select score;
// Execute the query.
foreach (int i in queryHighScores)
{
Console.Write(i + " ");
}
}
}
//Output: 97 92 81
select
절에서 생성된 시퀀스의 형식에 따라 쿼리 변수 queryHighScores
의 형식이 결정됩니다. 가장 단순한 경우에서는 select
절이 범위 변수를 지정합니다. 이렇게 하면 반환된 시퀀스에 데이터 소스와 동일한 형식의 요소가 포함됩니다. 자세한 내용은 LINQ 쿼리 작업의 형식 관계를 참조하세요. 그러나 select
절은 소스 데이터를 새 형식으로 변환(또는 프로젝션)하기 위한 강력한 메커니즘도 제공합니다. 자세한 내용은 LINQ를 통한 데이터 변환(C#)을 참조하세요.
예시
다음 예제에서는 select
절에 사용할 수 있는 모든 형식을 보여 줍니다. 각 쿼리에서 select
절과 쿼리 변수 형식(studentQuery1
, studentQuery2
등) 간의 관계를 확인합니다.
class SelectSample2
{
// Define some classes
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}";
}
public class ScoreInfo
{
public double Average { get; init; }
public int ID { get; init; }
}
// The primary data source
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"}
];
static void Main(string[] args)
{
SelectSample2 app = new SelectSample2();
// Produce a filtered sequence of unmodified Students.
IEnumerable<Student> studentQuery1 =
from student in app.students
where student.ID > 111
select student;
Console.WriteLine("Query1: select range_variable");
foreach (Student s in studentQuery1)
{
Console.WriteLine(s.ToString());
}
// Produce a filtered sequence of elements that contain
// only one property of each Student.
IEnumerable<String> studentQuery2 =
from student in app.students
where student.ID > 111
select student.Last;
Console.WriteLine("\r\n studentQuery2: select range_variable.Property");
foreach (string s in studentQuery2)
{
Console.WriteLine(s);
}
// Produce a filtered sequence of objects created by
// a method call on each Student.
IEnumerable<ContactInfo> studentQuery3 =
from student in app.students
where student.ID > 111
select student.GetContactInfo(app, student.ID);
Console.WriteLine("\r\n studentQuery3: select range_variable.Method");
foreach (ContactInfo ci in studentQuery3)
{
Console.WriteLine(ci.ToString());
}
// Produce a filtered sequence of ints from
// the internal array inside each Student.
IEnumerable<int> studentQuery4 =
from student in app.students
where student.ID > 111
select student.Scores[0];
Console.WriteLine("\r\n studentQuery4: select range_variable[index]");
foreach (int i in studentQuery4)
{
Console.WriteLine("First score = {0}", i);
}
// Produce a filtered sequence of doubles
// that are the result of an expression.
IEnumerable<double> studentQuery5 =
from student in app.students
where student.ID > 111
select student.Scores[0] * 1.1;
Console.WriteLine("\r\n studentQuery5: select expression");
foreach (double d in studentQuery5)
{
Console.WriteLine("Adjusted first score = {0}", d);
}
// Produce a filtered sequence of doubles that are
// the result of a method call.
IEnumerable<double> studentQuery6 =
from student in app.students
where student.ID > 111
select student.Scores.Average();
Console.WriteLine("\r\n studentQuery6: select expression2");
foreach (double d in studentQuery6)
{
Console.WriteLine("Average = {0}", d);
}
// Produce a filtered sequence of anonymous types
// that contain only two properties from each Student.
var studentQuery7 =
from student in app.students
where student.ID > 111
select new { student.First, student.Last };
Console.WriteLine("\r\n studentQuery7: select new anonymous type");
foreach (var item in studentQuery7)
{
Console.WriteLine("{0}, {1}", item.Last, item.First);
}
// Produce a filtered sequence of named objects that contain
// a method return value and a property from each Student.
// Use named types if you need to pass the query variable
// across a method boundary.
IEnumerable<ScoreInfo> studentQuery8 =
from student in app.students
where student.ID > 111
select new ScoreInfo
{
Average = student.Scores.Average(),
ID = student.ID
};
Console.WriteLine("\r\n studentQuery8: select new named type");
foreach (ScoreInfo si in studentQuery8)
{
Console.WriteLine("ID = {0}, Average = {1}", si.ID, si.Average);
}
// Produce a filtered sequence of students who appear on a contact list
// and whose average is greater than 85.
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;
Console.WriteLine("\r\n studentQuery9: select result of join clause");
foreach (ContactInfo ci in studentQuery9)
{
Console.WriteLine("ID = {0}, Email = {1}", ci.ID, ci.Email);
}
}
}
/* Output
Query1: select range_variable
Claire O'Donnell:112
Sven Mortensen:113
Cesar Garcia:114
studentQuery2: select range_variable.Property
O'Donnell
Mortensen
Garcia
studentQuery3: select range_variable.Method
ClaireO@Contoso.com,206-555-0298
SvenMort@Contoso.com,206-555-1130
CesarGar@Contoso.com,206-555-0521
studentQuery4: select range_variable[index]
First score = 75
First score = 88
First score = 97
studentQuery5: select expression
Adjusted first score = 82.5
Adjusted first score = 96.8
Adjusted first score = 106.7
studentQuery6: select expression2
Average = 72.25
Average = 84.5
Average = 88.25
studentQuery7: select new anonymous type
O'Donnell, Claire
Mortensen, Sven
Garcia, Cesar
studentQuery8: select new named type
ID = 112, Average = 72.25
ID = 113, Average = 84.5
ID = 114, Average = 88.25
studentQuery9: select result of join clause
ID = 114, Email = CesarGar@Contoso.com
*/
앞의 예제에서 studentQuery8
에 표시된 대로 반환된 시퀀스의 요소에 소스 요소의 속성 하위 집합만 포함하려는 경우도 있습니다. 반환된 시퀀스를 최대한 작게 유지하면 메모리 요구 사항을 줄이고 쿼리 실행 속도를 높일 수 있습니다. select
절에서 무명 형식을 만들고 개체 이니셜라이저를 사용하여 소스 요소의 적절한 속성으로 초기화하면 됩니다. 이 작업을 수행하는 방법의 예를 보려면 개체 및 컬렉션 이니셜라이저를 참조하세요.
설명
컴파일 시간에 select
절은 Select 표준 쿼리 연산자에 대한 메서드 호출로 변환됩니다.
참고 항목
.NET