from 절(C# 참조)
쿼리 식은 from
절로 시작해야 합니다. 또한 쿼리 식은 from
절로 시작하는 하위 쿼리를 포함할 수 있습니다. from
절은 다음 내용을 지정합니다.
쿼리 또는 하위 쿼리가 실행될 데이터 소스.
소스 시퀀스의 각 요소를 나타내는 지역 범위 변수.
범위 변수 및 데이터 소스 모두 강력한 형식입니다. from
절에서 참조되는 데이터 소스는 IEnumerable 또는 IEnumerable<T> 형식이거나 IQueryable<T>와 같은 파생 형식이어야 합니다.
다음 예제에서 numbers
는 데이터 소스이고 num
은 범위 변수입니다. var 키워드가 사용되어도 두 변수는 모두 강력한 형식입니다.
class LowNums
{
static void Main()
{
// A simple data source.
int[] numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];
// Create the query.
// lowNums is an IEnumerable<int>
var lowNums = from num in numbers
where num < 5
select num;
// Execute the query.
foreach (int i in lowNums)
{
Console.Write(i + " ");
}
}
}
// Output: 4 1 3 2 0
범위 변수
컴파일러는 데이터 소스가 IEnumerable<T>을 구현할 경우 범위 변수의 형식을 유추합니다. 예를 들어, 소스의 형식이 IEnumerable<Customer>
일 경우 범위 변수는 Customer
로 유추됩니다. 소스가 ArrayList와 같이 제네릭이 아닌 IEnumerable
형식인 경우에만 형식을 명시적으로 지정하면 됩니다. 자세한 내용은 LINQ를 사용하여 ArrayList를 쿼리하는 방법을 참조하세요.
위의 예제에서 num
은 int
형식으로 유추됩니다. 범위 변수가 강력한 형식이므로 범위 변수에서 메서드를 호출하거나 다른 작업에서 범위 변수를 사용할 수 있습니다. 예를 들어 select num
을 작성하는 대신에 select num.ToString()
을 작성하여 쿼리 식에서 정수 대신 문자열 시퀀스를 반환하게 할 수 있습니다. 또는 select num + 10
을 작성하여 식에서 14, 11, 13, 12, 10 시퀀스를 반환하게 할 수 있습니다. 자세한 내용은 select 절을 참조하세요.
범위 변수가 소스의 데이터를 실제로 저장하지 않는다는 매우 중요한 한 가지 차이점을 제외하면 범위 변수는 foreach 문의 반복 변수와 같습니다. 범위 변수는 단순히 쿼리 실행 시에 발생하는 작업을 쿼리에서 설명할 수 있게 하는 구문상의 편리함을 제공합니다. 자세한 내용은 LINQ 쿼리 소개(C#)를 참조하세요.
복합 from 절
경우에 따라 소스 시퀀스의 각 요소 자체가 시퀀스이거나 시퀀스를 포함할 수 있습니다. 예를 들어, 시퀀스의 각 학생 개체에 테스트 점수 목록이 포함된 IEnumerable<Student>
가 데이터 소스일 수 있습니다. 각 Student
요소 내의 내부 목록에 액세스하려면 복합 from
절을 사용합니다. 이 기술은 중첩된 foreach 문을 사용하는 것과 같습니다. where 또는 orderby 절을 둘 중 하나의 from
절에 추가하여 결과를 필터링할 수 있습니다. 다음 예제에서는 테스트 점수를 나타내는 정수의 내부 List
를 각각 포함하는 Student
개체의 시퀀스를 보여 줍니다. 내부 목록에 액세스하려면 복합 from
절을 사용합니다. 필요한 경우 두 from
절 사이에 다른 절을 삽입할 수 있습니다.
class CompoundFrom
{
// The element type of the data source.
public class Student
{
public required string LastName { get; init; }
public required List<int> Scores {get; init;}
}
static void Main()
{
// Use a collection initializer to create the data source. Note that
// each element in the list contains an inner sequence of scores.
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]}
];
// Use a compound from to access the inner sequence within each element.
// Note the similarity to a nested foreach statement.
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };
// Execute the queries.
Console.WriteLine("scoreQuery:");
// Rest the mouse pointer on scoreQuery in the following line to
// see its type. The type is IEnumerable<'a>, where 'a is an
// anonymous type defined as new {string Last, int score}. That is,
// each instance of this anonymous type has two members, a string
// (Last) and an int (score).
foreach (var student in scoreQuery)
{
Console.WriteLine("{0} Score: {1}", student.Last, student.score);
}
}
}
/*
scoreQuery:
Omelchenko Score: 97
O'Donnell Score: 91
Mortensen Score: 94
Garcia Score: 97
Beebe Score: 91
*/
여러 from 절을 사용하여 조인 수행
복합 from
절은 단일 데이터 소스의 내부 컬렉션에 액세스하는 데 사용됩니다. 그러나 독립 데이터 소스의 추가 쿼리를 생성하는 여러 from
절이 쿼리에 포함될 수도 있습니다. 이 기술을 사용하면 join 절로 수행할 수 없는 특정 형식의 조인 작업을 수행할 수 있습니다.
다음 예제는 두 개의 from
절을 사용하여 두 개의 데이터 소스의 완전한 크로스 조인을 구성하는 방법을 보여 줍니다.
class CompoundFrom2
{
static void Main()
{
char[] upperCase = ['A', 'B', 'C'];
char[] lowerCase = ['x', 'y', 'z'];
// The type of joinQuery1 is IEnumerable<'a>, where 'a
// indicates an anonymous type. This anonymous type has two
// members, upper and lower, both of type char.
var joinQuery1 =
from upper in upperCase
from lower in lowerCase
select new { upper, lower };
// The type of joinQuery2 is IEnumerable<'a>, where 'a
// indicates an anonymous type. This anonymous type has two
// members, upper and lower, both of type char.
var joinQuery2 =
from lower in lowerCase
where lower != 'x'
from upper in upperCase
select new { lower, upper };
// Execute the queries.
Console.WriteLine("Cross join:");
// Rest the mouse pointer on joinQuery1 to verify its type.
foreach (var pair in joinQuery1)
{
Console.WriteLine("{0} is matched to {1}", pair.upper, pair.lower);
}
Console.WriteLine("Filtered non-equijoin:");
// Rest the mouse pointer over joinQuery2 to verify its type.
foreach (var pair in joinQuery2)
{
Console.WriteLine("{0} is matched to {1}", pair.lower, pair.upper);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* 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
*/
여러 from
절을 사용하는 조인 작업에 대한 자세한 내용은 왼쪽 우선 외부 조인 수행을 참조하세요.
참고 항목
.NET