다음을 통해 공유


Method-Based 쿼리 구문 예제: 관계 탐색

Entity Framework의 탐색 속성은 연결의 끝에서 엔터티를 찾는 데 사용되는 바로 가기 속성입니다. 탐색 속성을 사용하면 사용자가 연결 집합을 통해 한 엔터티에서 다른 엔터티로 또는 한 엔터티에서 관련 엔터티로 이동할 수 있습니다. 이 항목에서는 LINQ to Entities 쿼리의 탐색 속성을 통해 관계를 탐색하는 방법의 메서드 기반 쿼리 구문에 대한 예제를 제공합니다.

이러한 예제에 사용된 AdventureWorks 판매 모델은 AdventureWorks 샘플 데이터베이스의 Contact, Address, Product, SalesOrderHeader 및 SalesOrderDetail 테이블에서 빌드됩니다.

이 항목의 예제에서는 다음 using/Imports 문을 사용합니다.

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Globalization;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Data.Common;

Option Explicit On
Option Strict On
Imports System.Data.Objects
Imports System.Globalization

예제 1

메서드 기반 쿼리 구문의 다음 예제에서는 SelectMany 메서드를 사용하여 성이 "Zhou"인 연락처의 모든 주문을 가져옵니다. Contact.SalesOrderHeader 탐색 속성은 각 연락처에 대한 SalesOrderHeader 개체의 컬렉션을 가져오는 데 사용됩니다.

string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> ordersQuery = context.Contacts
        .Where(c => c.LastName == lastName)
        .SelectMany(c => c.SalesOrderHeaders);

    foreach (var order in ordersQuery)
    {
        Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
            order.SalesOrderID, order.OrderDate, order.TotalDue);
    }
}
Dim lastName = "Zhou"
Using context As New AdventureWorksEntities
    Dim ordersQuery = context.Contacts _
    .Where(Function(c) c.LastName = lastName) _
    .SelectMany(Function(o) o.SalesOrderHeaders)

    For Each order In ordersQuery
        Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}", _
                order.SalesOrderID, order.OrderDate, order.TotalDue)
    Next
End Using

예제 2

메서드 기반 쿼리 구문의 다음 예제에서는 Select 메서드를 사용하여 모든 연락처 ID와 성이 "Zhou"인 각 연락처의 총 합계를 가져옵니다. Contact.SalesOrderHeader 탐색 속성은 각 연락처에 대한 SalesOrderHeader 개체의 컬렉션을 가져오는 데 사용됩니다. Sum 메서드는 Contact.SalesOrderHeader 탐색 속성을 사용하여 각 연락처에 대한 모든 주문으로 인한 합계를 합산합니다.

string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var ordersQuery = context.Contacts
        .Where(c => c.LastName == lastName)
        .Select(c => new
        {
            ContactID = c.ContactID,
            Total = c.SalesOrderHeaders.Sum(o => o.TotalDue)
        });

    foreach (var contact in ordersQuery)
    {
        Console.WriteLine($"Contact ID: {contact.ContactID} Orders total: {contact.Total}");
    }
}
Dim lastName = "Zhou"
Using context As New AdventureWorksEntities
    Dim ordersQuery = context.Contacts _
    .Where(Function(c) c.LastName = lastName) _
    .Select(Function(c) New With _
                {.ContactID = c.ContactID, _
                .Total = c.SalesOrderHeaders.Sum(Function(o) o.TotalDue)})

    For Each order In ordersQuery
        Console.WriteLine("Contact ID: {0} Orders total: {1}", order.ContactID, order.Total)
    Next
End Using

예제 3

메서드 기반 쿼리 구문의 다음 예제에서는 성이 "Zhou"인 연락처의 모든 순서를 가져옵니다. Contact.SalesOrderHeader 탐색 속성은 각 연락처에 대한 SalesOrderHeader 개체의 컬렉션을 가져오는 데 사용됩니다. 연락처의 이름과 주문은 익명 형식으로 반환됩니다.

string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var ordersQuery = context.Contacts
        .Where(c => c.LastName == lastName)
        .Select(c => new { LastName = c.LastName, Orders = c.SalesOrderHeaders });

    foreach (var order in ordersQuery)
    {
        Console.WriteLine($"Name: {order.LastName}");
        foreach (SalesOrderHeader orderInfo in order.Orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}
Dim lastName = "Zhou"
Using context As New AdventureWorksEntities
    Dim ordersQuery = context.Contacts _
    .Where(Function(c) c.LastName = lastName) _
    .Select(Function(o) New With _
                {.LastName = o.LastName, _
                 .Orders = o.SalesOrderHeaders})

    For Each order In ordersQuery
        Console.WriteLine("Name: {0}", order.LastName)
        For Each orderInfo In order.Orders

            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}", _
                    orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue)
        Next

        Console.WriteLine("")
    Next
End Using

예제 4

다음 예제에서는 SalesOrderHeader.AddressSalesOrderHeader.Contact 탐색 속성을 사용하여 각 순서와 연결된 AddressContact 개체의 컬렉션을 가져옵니다. 연락처의 성, 거리 주소, 판매 주문 번호 및 시애틀 시로의 각 주문에 대한 총액은 익명 형식으로 반환됩니다.

string city = "Seattle";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var ordersQuery = context.SalesOrderHeaders
        .Where(o => o.Address.City == city)
        .Select(o => new
        {
            ContactLastName = o.Contact.LastName,
            ContactFirstName = o.Contact.FirstName,
            StreetAddress = o.Address.AddressLine1,
            OrderNumber = o.SalesOrderNumber,
            TotalDue = o.TotalDue
        });

    foreach (var orderInfo in ordersQuery)
    {
        Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName);
        Console.WriteLine($"Street address: {orderInfo.StreetAddress}");
        Console.WriteLine($"Order number: {orderInfo.OrderNumber}");
        Console.WriteLine($"Total Due: {orderInfo.TotalDue}");
        Console.WriteLine("");
    }
}
Dim city = "Seattle"
Using context As New AdventureWorksEntities
    Dim ordersQuery = context.SalesOrderHeaders _
             .Where(Function(o) o.Address.City = city) _
             .Select(Function(o) New With { _
                            .ContactLastName = o.Contact.LastName, _
                            .ContactFirstName = o.Contact.FirstName, _
                            .StreetAddress = o.Address.AddressLine1, _
                            .OrderNumber = o.SalesOrderNumber, _
                            .TotalDue = o.TotalDue _
             })

    For Each orderInfo In ordersQuery
        Console.WriteLine("Name: {0}, {1}", orderInfo.ContactLastName, orderInfo.ContactFirstName)
        Console.WriteLine("Street address: {0}", orderInfo.StreetAddress)
        Console.WriteLine("Order number: {0}", orderInfo.OrderNumber)
        Console.WriteLine("Total Due: {0}", orderInfo.TotalDue)
        Console.WriteLine("")
    Next

End Using

예제 5

다음 예제에서는 Where 메서드를 사용하여 2003년 12월 1일 이후에 수행된 주문을 찾은 다음 order.SalesOrderDetail 탐색 속성을 사용하여 각 주문에 대한 세부 정보를 가져옵니다.

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<SalesOrderHeader> query =
        from order in context.SalesOrderHeaders
        where order.OrderDate >= new DateTime(2003, 12, 1)
        select order;

    Console.WriteLine("Orders that were made after December 1, 2003:");
    foreach (SalesOrderHeader order in query)
    {
        Console.WriteLine($"OrderID {order.SalesOrderID} Order date: {order.OrderDate:d} ");
        foreach (SalesOrderDetail orderDetail in order.SalesOrderDetails)
        {
            Console.WriteLine($"  Product ID: {orderDetail.ProductID} Unit Price {orderDetail.UnitPrice}");
        }
    }
}
Using context As New AdventureWorksEntities
    Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders

    Dim query = _
        From order In orders _
        Where order.OrderDate >= New DateTime(2003, 12, 1) _
        Select order

    Console.WriteLine("Orders that were made after December 1, 2003:")
    For Each order In query
        Console.WriteLine("OrderID {0} Order date: {1:d} ", _
                order.SalesOrderID, order.OrderDate)
        For Each orderDetail In order.SalesOrderDetails
            Console.WriteLine("  Product ID: {0} Unit Price {1}", _
                orderDetail.ProductID, orderDetail.UnitPrice)
        Next
    Next
End Using

참고하십시오