Share via


쿼리 결과

LINQ to Entities 쿼리가 명령 트리로 변환되어 실행되고 나면 일반적으로 쿼리 결과가 다음 중 하나의 형태로 반환됩니다.

  • 개념적 모델에 있는 0개 이상의 형식화된 엔터티 개체 컬렉션 또는 복합 형식의 프로젝션

  • 개념적 모델에서 지원되는 CLR 형식

  • 인라인 컬렉션

  • 익명 형식

쿼리가 데이터 소스에 대해 실행된 경우 그 결과는 CLR 형식으로 구체화되어 클라이언트에 반환됩니다. 모든 개체 구체화는 Entity Framework에 의해 수행됩니다. Entity Framework와 CLR 간의 매핑 실패로 인해 오류가 발생하면 개체 구체화 동안 예외가 throw됩니다.

쿼리 실행으로 기본 개념적 모델 형식이 반환되는 경우, 이 결과는 Entity Framework와 연결되지 않은 독립 실행형 CLR 형식으로 구성됩니다. 이와 달리 쿼리가 형식화된 엔터티 개체 컬렉션을 반환하는 경우(ObjectQuery<T>로 표현됨), 이러한 형식은 개체 컨텍스트에서 추적됩니다. 자식/부모 컬렉션, 변경 추적, 다형성 등의 모든 개체 동작은 Entity Framework에 정의되어 있으며, 이런 기능을 Entity Framework에 정의된 그대로 사용할 수 있습니다. 자세한 내용은 개체 작업을 참조하세요.

쿼리에서 반환된 구조 형식(예: 익명 형식 및 null 허용 복합 형식)의 값은 null일 수 있습니다. 반환된 엔터티의 EntityCollection<TEntity> 속성 값 또한 null일 수 있습니다. 이것은 값이 null인 엔터티 컬렉션 속성을 프로젝션했기 때문일 수 있습니다. 예를 들면, 요소가 없는 FirstOrDefault에 대해 ObjectQuery<T>를 호출하는 경우가 있습니다.

특정 상황에서는 쿼리가 실행 과정에서 구체화된 결과를 생성하는 것처럼 보일 수도 있지만, 쿼리는 서버에서 실행되며 엔터티 개체가 CLR에서 구체화되는 일은 없습니다. 이런 특징은 개체 구체화의 부작용에 좌우되는 경우 문제가 될 수 있습니다.

다음 예제에서는 MyContact 속성을 가진 사용자 지정 클래스 LastName를 보여 줍니다. LastName 속성이 설정되면 count 변수가 증가합니다. 다음 쿼리를 실행하면, 첫 번째 쿼리에서는 count가 증가하는 반면, 두 번째 쿼리에서는 그렇지 않습니다. 이것은 두 번째 쿼리의 LastName 속성이 결과에서 프로젝션되고 MyContact 클래스가 저장소에 대한 쿼리 실행에 필요가 없어서 생성되지 않기 때문입니다.

public static int count = 0;

static void Main(string[] args)
{
    using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
    {

        var query1 = AWEntities
           .Contacts
           .Where(c => c.LastName == "Jones")
           .Select(c => new MyContact { LastName = c.LastName });

        // Execute the first query and print the count.
        query1.ToList();
        Console.WriteLine("Count: " + count);

        //Reset the count variable.
        count = 0;

        var query2 = AWEntities
           .Contacts
           .Where(c => c.LastName == "Jones")
           .Select(c => new MyContact { LastName = c.LastName })
           .Select(my => my.LastName);

        // Execute the second query and print the count.
        query2.ToList();
        Console.WriteLine("Count: " + count);
    }

    Console.WriteLine("Hit enter...");
    Console.Read();
}
Public count As Integer = 0

Sub Main()

    Using AWEntities As New AdventureWorksEntities()

        Dim query1 = AWEntities.Contacts _
        .Where(Function(c) c.LastName = "Jones") _
        .Select(Function(c) New MyContact With {.LastName = c.LastName})

        ' Execute the first query and print the count.
        query1.ToList()
        Console.WriteLine("Count: " & count)

        ' Reset the count variable.
        count = 0

        Dim query2 = AWEntities _
        .Contacts() _
        .Where(Function(c) c.LastName = "Jones") _
        .Select(Function(c) New MyContact With {.LastName = c.LastName}) _
        .Select(Function(x) x.LastName)

        ' Execute the second query and print the count.
        query2.ToList()
        Console.WriteLine("Count: " & count)

    End Using
End Sub
public class MyContact
{

    String _lastName;

    public string LastName
    {
        get
        {
            return _lastName;
        }

        set
        {
            _lastName = value;
            count++;
        }
    }
}
Public Class MyContact

    Private _lastName As String

    Public Property LastName() As String
        Get
            Return _lastName
        End Get

        Set(ByVal value As String)
            _lastName = value
            count += 1
        End Set
    End Property

End Class