개체 쿼리(Entity Framework)

ObjectQuery 제네릭 클래스는 0개 이상의 형식화된 개체로 구성된 컬렉션을 반환할 수 있는 쿼리를 나타냅니다. ObjectQuery는 쿼리를 작성하고 실행하는 데 필요한 연결 및 메타데이터 정보를 포함하는 ObjectContext에 속해 있습니다. new 연산자를 사용하여 ObjectQuery를 생성하고 이 생성자에 쿼리 문자열과 개체 컨텍스트를 전달할 수 있습니다. 그러나 보다 일반적인 시나리오는 ObjectContext 파생 클래스의 속성을 사용하여 엔터티 집합의 컬렉션을 나타내는 ObjectQuery 인스턴스를 가져오는 것입니다. 일반적으로 ObjectContext는 Entity Framework 도구에서 생성된 클래스나 POCO 클래스에 의해 서브클래싱되며, 이 개체 컨텍스트의 속성은 엔터티 집합을 ObjectQuery(.NET Framework 버전 3.5 SP1의 경우) 또는 ObjectSet(.NET Framework 버전 4의 경우)으로 반환합니다. ObjectSet 클래스는 ObjectQuery 클래스를 확장하여 형식화된 엔터티 집합의 컨텍스트에서 개체 추가 및 삭제와 같은 기능을 제공합니다.

기본 ObjectQuery는 지정된 형식의 모든 엔터티를 반환하는 시작 쿼리를 제공합니다. LINQ to Entities 또는 쿼리 작성기 메서드를 사용하여 이 쿼리를 보다 구체화할 수 있습니다.

다음 예제에서는 Products의 컬렉션에 대한 개체 컨텍스트를 쿼리합니다.

Using context As New AdventureWorksEntities
    Dim products As ObjectSet(Of Product) = context.Products

    Dim productsQuery = _
        From product In products _
        Select product

    Console.WriteLine("Product Names:")
    For Each product In productsQuery
        Console.WriteLine(product.Name)
    Next
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Product> productsQuery = from product in context.Products
                                        select product;

    Console.WriteLine("Product Names:");
    foreach (var prod in productsQuery)
    {
        Console.WriteLine(prod.Name);
    }
}

쿼리 실행

개체 쿼리는 다음과 같은 경우에 실행됩니다.

쿼리 실행의 결과로 데이터 소스에서 아무 것도 반환되지 않은 경우 결과에는 null이 아니라 빈 컬렉션이 포함됩니다.

Entity Framework 에 의해 실행된 쿼리는 데이터 소스의 데이터에 대해 확인되며 해당 결과는 개체 컨텍스트에서 새 개체를 반영하지 않습니다. 쿼리되고 있는 것과 ID가 동일한 엔터티가 이미 컨텍스트에 연결되어 있으면 데이터 소스에서 가져온 데이터와 컨텍스트에 이미 있는 데이터가 쿼리의 MergeOption에 따라 병합됩니다. 캐시에 있는 데이터를 가져오려면 ObjectStateManager 클래스의 GetObjectStateEntries 메서드를 사용합니다. ObjectStateManager는 개체 컨텍스트 내에서 개체의 상태를 관리하므로 추가, 수정 및 변경되지 않은 모든 개체를 가져오려면 EntityState 값인 Added, ModifiedUnchanged의 비트 OR을 GetObjectStateEntries 메서드에 전달하면 됩니다. 자세한 내용은 로컬 쿼리를 수행하는 방법을 보여 주는 블로그를 참조하십시오.

다음 예제에서는 Execute 메서드를 호출하여 쿼리를 실행합니다.

Using context As New AdventureWorksEntities()
    Dim query As ObjectSet(Of Product) = context.Products

    ' Execute the query and get the ObjectResult. 
    Dim queryResult As ObjectResult(Of Product) = query.Execute(MergeOption.AppendOnly)
    ' Iterate through the collection of Product items. 
    For Each result As Product In queryResult
        Console.WriteLine("{0}", result.Name)
    Next
End Using
using (AdventureWorksEntities context =
    new AdventureWorksEntities())
{
    ObjectSet<Product> query = context.Products;

    // Execute the query and get the ObjectResult.
    ObjectResult<Product> queryResult = query.Execute(MergeOption.AppendOnly);
    // Iterate through the collection of Product items.
    foreach (Product result in queryResult)
        Console.WriteLine("{0}", result.Name);
}

쿼리 프로젝션

쿼리 개체는 대개 개념적 모델 데이터를 엔터티 개체로 반환하는 데 사용되지만, 중첩된 결과와 익명 프로젝션의 경우 DbDataRecord 개체를 반환하거나 단일 값 집합의 경우 기본 CLR 형식을 반환할 수도 있습니다.

LINQ to Entities 와 Entity SQL 은 모두 쿼리 프로젝션을 지원합니다. 쿼리 프로젝션과 관련하여 다음 사항을 고려해야 합니다.

  • 몇몇 확장 메서드는 입력으로 많은 결과의 컬렉션을 필요로 합니다. ObjectQuery가 단일 스칼라 결과가 포함된 컬렉션을 반환하는 쿼리를 나타내고 이러한 확장 메서드 중 하나가 호출되는 경우 다음 예제와 같이 ArgumentException이 throw됩니다.

    ' Define a query projection that returns 
    ' a collection with a single scalar result.
    Dim scalarQuery As New ObjectQuery(Of Int32)("100", context)
    
    ' Calling an extension method that requires a collection 
    ' will result in an exception. 
    Dim hasValues As Boolean = scalarQuery.Any()
    
    // Define a query projection that returns 
    // a collection with a single scalar result.
    ObjectQuery<Int32> scalarQuery =
        new ObjectQuery<Int32>("100", context);
    
    // Calling an extension method that requires a collection
    // will result in an exception.
    bool hasValues = scalarQuery.Any();
    
  • ObjectQuery를 기본 형식으로 프로젝션했을 때 null 값이 반환되는 경우, null을 허용하는 버전의 형식을 사용해야 합니다. SalesOrderHeader 개체의 ShipDate 속성이 null 값을 반환할 수 있으므로 다음 쿼리에서는 null을 허용하는 DateTime을 사용합니다.

    Dim shipDateQuery As ObjectQuery(Of Nullable(Of DateTime)) = _
        context.SalesOrderHeaders.Where("it.CustomerID = @contactId", _
            New ObjectParameter("contactId", contactId)).SelectValue(Of Nullable(Of DateTime))("it.ShipDate")
    
    ObjectQuery<Nullable<DateTime>> shipDateQuery =
        context.SalesOrderHeaders
        .Where("it.CustomerID = @contactId",
            new ObjectParameter("contactId", contactId))
        .SelectValue<Nullable<DateTime>>("it.ShipDate");
    

    자세한 내용은 Nullable 형식(Visual Basic 프로그래밍 가이드) 또는 Nullable Types (C# Programming Guide)을 참조하십시오.

저장소 명령 보기

개념적 모델을 쿼리할 때, Entity Framework 에서는 개념적 모델 기반의 LINQ to Entities 및 Entity SQL 쿼리를 데이터 소스에 대한 동일한 쿼리로 변환합니다. Entity Framework 에서는 System.Data.Objects.ObjectQuery.ToTraceStringSystem.Data.EntityClient.EntityCommand.ToTraceString 메서드를 제공하므로 데이터 소스에 대해 추적을 실행할 필요 없이 런타임에 이러한 저장소 명령을 볼 수 있습니다. 자세한 내용은 방법: 저장소 명령 보기(Entity Framework)를 참조하십시오.

EntityKey로 개체 검색

엔터티의 키 값을 아는 경우 명시적으로 개체 쿼리를 만들어 실행하지 않고 데이터 소스에서 해당 개체를 검색할 수 있습니다. ObjectContextGetObjectByKeyTryGetObjectByKey 메서드에서는 지정된 EntityKey를 가진 개체를 개체 컨텍스트로 반환합니다. GetObjectByKey를 사용하는 경우 제공된 EntityKey가 기존 엔터티와 일치하지 않으면 ObjectNotFoundException을 처리해야 합니다. 자세한 내용은 방법: 개체 키를 사용하여 특정 개체 반환(Entity Framework)을 참조하십시오.

참고 항목

개념

개념적 모델 쿼리(Entity Framework)
ObjectSet 사용(Entity Framework)
컴파일된 쿼리(LINQ to Entities)