다음을 통해 공유


첫 번째 LINQ 쿼리 작성(Visual Basic)

쿼리는 데이터 원본에서 데이터를 검색하는 식입니다. 쿼리는 전용 쿼리 언어로 표현됩니다. 시간이 지남에 따라 관계형 데이터베이스용 SQL 및 XML용 XQuery와 같은 다양한 유형의 데이터 원본에 대해 다양한 언어가 개발되었습니다. 따라서 애플리케이션 개발자가 지원되는 데이터 원본 또는 데이터 형식의 각 형식에 대한 새 쿼리 언어를 학습해야 합니다.

LINQ(Language-Integrated Query)는 다양한 종류의 데이터 원본 및 형식에서 데이터를 사용하기 위한 일관된 모델을 제공하여 상황을 간소화합니다. LINQ 쿼리에서는 항상 개체를 사용합니다. 동일한 기본 코딩 패턴을 사용하여 XML 문서, SQL 데이터베이스, ADO.NET 데이터 세트 및 엔터티, .NET Framework 컬렉션 및 LINQ 공급자를 사용할 수 있는 기타 원본 또는 형식의 데이터를 쿼리하고 변환합니다. 이 문서에서는 기본 LINQ 쿼리를 만들고 사용하는 세 가지 단계를 설명합니다.

쿼리 작업의 세 단계

LINQ 쿼리 작업은 다음 세 가지 작업으로 구성됩니다.

  1. 데이터 소스나 여러 소스를 확보하십시오.

  2. 쿼리를 만듭니다.

  3. 쿼리를 실행합니다.

LINQ에서 쿼리 실행은 쿼리 생성과 다릅니다. 쿼리를 만드는 것만으로는 데이터를 검색하지 않습니다. 이 점은 이 항목의 뒷부분에서 자세히 설명합니다.

다음 예제에서는 쿼리 작업의 세 부분을 보여 줍니다. 이 예제에서는 데모를 위해 정수 배열을 편리한 데이터 원본으로 사용합니다. 그러나 다른 데이터 원본에도 동일한 개념이 적용됩니다.

비고

프로젝트 디자이너(Visual Basic)의 컴파일 페이지에서옵션 유추기로 설정되어 있는지 확인합니다.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

출력:

0 2 4 6

데이터 원본

이전 예제의 데이터 원본은 배열이므로 제네릭 IEnumerable<T> 인터페이스를 암시적으로 지원합니다. LINQ 쿼리에 대한 데이터 원본으로 배열을 사용할 수 있는 것은 바로 이 사실입니다. 제네릭 IEnumerable<T> 과 같은 파생 인터페이스 또는 지원하는 IQueryable<T>형식을 쿼리 가능한 형식이라고 합니다.

암시적으로 쿼리 가능한 형식인 배열은 LINQ 데이터 원본으로 사용하기 위해 수정 또는 특별한 처리가 필요하지 않습니다. 컬렉션 형식에도 동일하게 적용됩니다. 이는 IEnumerable<T>를 지원하는 모든 컬렉션 형식에 해당하며, 제네릭 List<T>, Dictionary<TKey,TValue>, 및 .NET Framework 클래스 라이브러리의 다른 클래스들이 포함됩니다.

원본 데이터가 아직 구현 IEnumerable<T>되지 않은 경우 해당 데이터 원본에 대한 표준 쿼리 연산 자의 기능을 구현하려면 LINQ 공급자가 필요합니다. 예를 들어 LINQ to XML은 다음 예제와 같이 XML 문서를 쿼리 가능한 XElement 형식으로 로드하는 작업을 처리합니다. 표준 쿼리 연산자에 대한 자세한 내용은 표준 쿼리 연산자 개요(Visual Basic)를 참조하세요.

' Create a data source from an XML document.
Dim contacts = XElement.Load("c:\myContactList.xml")

LINQ to SQL을 사용하면 먼저 디자인 타임에 수동으로 또는 Visual Studio의 Visual Studio에서 LINQ to SQL 도구를 사용하여 개체 관계형 매핑을 만듭니다. 개체에 대한 쿼리를 작성하고 런타임에 LINQ to SQL에서 데이터베이스와의 통신을 처리합니다. 다음 예제 customers 에서는 데이터베이스의 특정 테이블을 나타내며 Table<TEntity> 제네릭 IQueryable<T>을 지원합니다.

' Create a data source from a SQL table.
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)

특정 유형의 데이터 원본을 만드는 방법에 대한 자세한 내용은 다양한 LINQ 공급자에 대한 설명서를 참조하세요. (이러한 공급자 목록은 LINQ(Language-Integrated 쿼리)를 참조하세요.) 기본 규칙은 간단합니다. LINQ 데이터 원본은 제네릭 IEnumerable<T> 인터페이스를 지원하는 모든 개체 또는 해당 인터페이스에서 상속되는 인터페이스입니다.

비고

제네릭 ArrayList 이 아닌 인터페이스를 지원하는 형식 IEnumerable 도 LINQ 데이터 원본으로 사용할 수 있습니다. 를 사용하는 예제는 ArrayList방법: LINQ를 사용하여 ArrayList 쿼리(Visual Basic)를 참조하세요.

쿼리

쿼리에서 데이터 원본 또는 원본에서 검색할 정보를 지정합니다. 또한 정보를 반환하기 전에 정렬, 그룹화 또는 구조화할 방법을 지정할 수도 있습니다. 쿼리 만들기를 사용하도록 설정하기 위해 Visual Basic은 새 쿼리 구문을 언어에 통합했습니다.

실행될 때 다음 예제의 쿼리는 정수 배열 numbers의 모든 짝수 숫자를 반환합니다.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

쿼리 식에는 세 개의 절이 있습니다: From, Where, 그리고 Select. 각 쿼리 식 절의 특정 함수와 용도는 기본 쿼리 작업(Visual Basic)에서 설명합니다. 자세한 내용은 쿼리를 참조하세요. LINQ에서 쿼리 정의는 종종 변수에 저장되고 나중에 실행됩니다. 이전 예제와 같은 evensQuery 쿼리 변수는 쿼리 가능한 형식이어야 합니다. evensQuery의 형식은 IEnumerable(Of Integer)이며, 로컬 형식 유추를 사용하여 컴파일러에 의해 할당됩니다.

쿼리 변수 자체는 아무 작업도 수행하지 않고 데이터를 반환하지 않는다는 점을 기억해야 합니다. 쿼리 정의만 저장합니다. 이전 예제에서는 쿼리를 For Each 실행하는 루프입니다.

쿼리 실행

쿼리 실행은 쿼리 만들기와 별개입니다. 쿼리 만들기는 쿼리를 정의하지만 실행은 다른 메커니즘에 의해 트리거됩니다. 쿼리가 정의되는 즉시(즉시 실행) 쿼리를 실행하거나 정의를 저장할 수 있으며 나중에 쿼리를 실행할 수 있습니다(지연된 실행).

지연된 실행

일반적인 LINQ 쿼리는 정의된 이전 예제 evensQuery 의 쿼리와 유사합니다. 쿼리를 만들지만 즉시 실행하지는 않습니다. 대신 쿼리 정의는 쿼리 변수 evensQuery에 저장됩니다. 일반적으로 값 시퀀스를 반환하는 루프를 For Each 사용하거나 표준 쿼리 연산자(예: Count 또는 Max)를 적용하여 나중에 쿼리를 실행합니다. 이 프로세스를 지연된 실행이라고 합니다.

' Query execution that results in a sequence of values.
For Each number In evensQuery
    Console.Write(number & " ")
Next

' Query execution that results in a single value.
Dim evens = evensQuery.Count()

값 시퀀스의 경우 루프의 반복 변수 For Each (number 이전 예제)를 사용하여 검색된 데이터에 액세스합니다. 쿼리 변수는 쿼리 결과가 아닌 쿼리 정의를 보유하므로 쿼리 변수 evensQuery를 두 번 이상 사용하여 원하는 만큼 자주 쿼리를 실행할 수 있습니다. 예를 들어 별도의 애플리케이션에서 지속적으로 업데이트되는 데이터베이스가 애플리케이션에 있을 수 있습니다. 해당 데이터베이스에서 데이터를 검색하는 쿼리를 만든 후에는 루프를 For Each 사용하여 쿼리를 반복적으로 실행하고 매번 최신 데이터를 검색할 수 있습니다.

다음 예제에서는 지연된 실행의 작동 방식을 보여 줍니다. 루프를 evensQuery2 사용하여 정의하고 실행한 후 For Each 이전 예제와 같이 데이터 원본 numbers 의 일부 요소가 변경됩니다. 그런 다음 두 번째 For Each 루프가 다시 실행됩니다 evensQuery2 . 루프에서 새 값을 For Each사용하여 쿼리를 다시 실행하기 때문에 numbers 결과는 두 번째로 다릅니다.

Dim numberArray() = {0, 1, 2, 3, 4, 5, 6}

Dim evensQuery2 = From num In numberArray
                  Where num Mod 2 = 0
                  Select num

Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8

' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

출력:

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

즉시 실행

쿼리의 지연 실행에서 쿼리 정의는 나중에 실행하기 위해 쿼리 변수에 저장됩니다. 즉시 실행 시 쿼리는 정의 시 실행됩니다. 쿼리 결과의 개별 요소에 액세스해야 하는 메서드를 적용하면 실행이 트리거됩니다. 단일 값을 반환하는 표준 쿼리 연산자 중 하나를 사용하여 즉시 실행해야 하는 경우가 많습니다. 예는 Count, Max, AverageFirst. 이러한 표준 쿼리 연산자는 단일 결과를 계산하고 반환하기 위해 적용되는 즉시 쿼리를 실행합니다. 단일 값을 반환하는 표준 쿼리 연산자에 대한 자세한 내용은 집계 작업, 요소 작업수량자 연산을 참조하세요.

다음 쿼리는 정수 배열의 짝수 수를 반환합니다. 쿼리 정의는 저장 numEvens 되지 않으며 간단합니다 Integer.

Dim numEvens = (From num In numbers
                Where num Mod 2 = 0
                Select num).Count()

Aggregate 메서드를 사용하여 동일한 결과를 얻을 수 있습니다.

Dim numEvensAgg = Aggregate num In numbers
                  Where num Mod 2 = 0
                  Select num
                  Into Count()

쿼리 또는 쿼리 변수에서 ToList 또는 ToArray 메서드를 호출하여 쿼리를 강제로 실행할 수도 있습니다(즉시 또는 지연 실행). 다음 코드에 예시가 나와 있습니다.

' Immediate execution.
Dim evensList = (From num In numbers
                 Where num Mod 2 = 0
                 Select num).ToList()

' Deferred execution.
Dim evensQuery3 = From num In numbers
                  Where num Mod 2 = 0
                  Select num
' . . .
Dim evensArray = evensQuery3.ToArray()

이전 예제 evensQuery3 에서는 쿼리 변수이지만 evensList 목록이며 evensArray 배열입니다.

ToList 즉시 실행 또는 ToArray 강제 실행은 쿼리를 즉시 실행하고 결과를 단일 컬렉션 개체에 캐시하려는 시나리오에서 특히 유용합니다. 이러한 메서드에 대한 자세한 내용은 데이터 형식 변환을 참조하세요.

IEnumerable 메서드 같은 IEnumerable.GetEnumerator 메서드를 사용하여 쿼리를 실행할 수도 있습니다.

참고하십시오