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 n + 10을 작성하여 식에서 14, 11, 13, 12, 10 시퀀스를 반환하게 할 수 있습니다.자세한 내용은 select 절(C# 참조)를 참조하십시오.
범위 변수가 소스의 데이터를 실제로 저장하지 않는다는 매우 중요한 차이점을 제외하면 범위 변수는 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 string LastName { get; set; }
public List<int> Scores {get; set;}
}
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 List<Student>
{
new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}},
new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}},
new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}},
new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}},
new Student {LastName="Beebe", Scores= new List<int> {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);
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/*
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 절을 사용하는 조인 작업에 대한 자세한 내용은 방법: 사용자 지정 조인 작업 수행(C# 프로그래밍 가이드)을 참조하십시오.