LINQ에서 Include ()는 무엇을합니까?


96

나는 많은 연구를 시도했지만 나는 더 많은 db 녀석이기 때문에 MSDN의 설명조차도 나에게 의미가 없습니다. 누구든지 설명해 주시고 쿼리 Include()용어에서 어떤 진술이 수행 되는지에 대한 몇 가지 예를 제공 할 수 있습니까 SQL?


매우 기본적이며, 일부 집계 연산자 만 알고 있습니다. Select, Where, Order by. LINQ에서 JOIN이나 Include를 시도하지 않았습니다. 저의 궁극적 인 목표는 이러한 LINQ 쿼리를 SQL로 다시 작성할 수있는 것이 었습니다
CJ

답변:


169

예를 들어 모든 고객 목록을 얻고 싶다고 가정 해 보겠습니다.

var customers = context.Customers.ToList();

그리고의 각 가정하자 Customer객체가 자사의 설정에 대한 참조를 가지고 Orders, 각는 것을 Order참조가에 LineItems있는도를 참조 할 수있다 Product.

보시다시피 관련 항목이 많은 최상위 개체를 선택하면 여러 소스에서 데이터를 가져와야하는 쿼리가 발생할 수 있습니다. 성능 측정으로 Include()동일한 쿼리의 일부로 데이터베이스에서 읽어야하는 관련 엔터티를 나타낼 수 있습니다.

동일한 예를 사용하면 관련된 모든 주문 헤더를 가져올 수 있지만 다른 레코드는 가져올 수 없습니다.

var customersWithOrderDetail = context.Customers.Include("Orders").ToList();

SQL을 요청한 이후 마지막으로,없는 첫 번째 문 Include()은 간단한 문을 생성 할 수 있습니다.

SELECT * FROM Customers;

호출하는 마지막 문장 Include("Orders")은 다음과 같습니다.

SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;

1
감사합니다. 귀하의 예제를 사용하여 LineItems및을 포함 Products하려면 LINQ 쿼리가 다음과 같이 표시되어야 한다고 말할 수 var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();있습니까?
CJ

2
예, 여러 호출을 연결 Include()하여 서로 다른 "경로"를 따라 개체를 캡처 할 수 있습니다 . 동일한 경로에있는 개체를 원하는 경우 전체 경로를 지정하는 하나의 호출 만하면됩니다. 이후 LineItemsProducts별도의 전화를해야합니까 어떤 경로 구성 요소를 공유하지 않습니다.
Yuck

Include를 반드시 사용해야합니까? 나는 그것을 사용하지 않고 관련 개체를 얻을 수있는 솔루션을 개발했다고 확신합니다.
Jepzen

@Jepzen 지연로드 된 엔티티를 사용하는지 여부에 따라 다릅니다.

@Yuck, 나는 이것이 지연 로딩을 사용할 때 작동한다고 믿습니다. eager 로딩의 경우 "include"문을 사용할 필요가 없지만 이것은 확실히 성능 문제를 초래할 것입니다. 이것에 대해 나를 수정하십시오.
sam

27

"Include"가 eager loading의 일부임을 추가하고 싶었습니다. Microsoft의 Entity Framework 6 자습서에 설명되어 있습니다. 링크는 다음과 같습니다. https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the asp-net-mvc- 응용 프로그램에서 -entity-framework-in-an-asp-net-mvc-application


링크 된 페이지에서 발췌 :

다음은 Entity Framework가 엔터티의 탐색 속성에 관련 데이터를로드 할 수있는 몇 가지 방법입니다.

지연 로딩. 엔터티를 처음 읽을 때 관련 데이터는 검색되지 않습니다. 그러나 탐색 속성에 처음 액세스하려고하면 해당 탐색 속성에 필요한 데이터가 자동으로 검색됩니다. 이로 인해 여러 쿼리가 데이터베이스로 전송됩니다. 하나는 항목 자체에 대한 것이고 하나는 항목에 대한 관련 데이터를 검색해야 할 때마다 하나씩입니다. DbContext 클래스는 기본적으로 지연로드를 활성화합니다.

열망 로딩. 엔터티를 읽으면 관련 데이터도 함께 검색됩니다. 일반적으로 필요한 모든 데이터를 검색하는 단일 조인 쿼리가 생성됩니다. Include메소드 를 사용하여 즉시로드를 지정합니다 .

명시 적 로딩. 이는 코드에서 관련 데이터를 명시 적으로 검색한다는 점을 제외하면 지연로드와 유사합니다. 탐색 속성에 액세스 할 때 자동으로 발생하지 않습니다. 엔터티에 대한 개체 상태 관리자 항목을 가져오고 컬렉션에 대해서는 Collection.Load 메서드를 호출하거나 단일 엔터티를 보유하는 속성에 대해서는 Reference.Load 메서드를 호출하여 관련 데이터를 수동으로로드합니다. (다음 예제에서 관리자 탐색 속성을로드하려는 경우 으로 대체 Collection(x => x.Courses)합니다 Reference(x => x.Administrator).) 일반적으로 지연로드를 해제 한 경우에만 명시 적로드를 사용합니다.

속성 값을 즉시 검색하지 않기 때문에 지연로드와 명시 적로드를 모두 지연로드라고도합니다.


3
SO =)에 오신 것을 환영합니다. 제안 사항이지만 이와 같은 답변을 할 때 가능한 경우 코드 조각을 포함하십시오. 불행히도 링크가 끊어 질 수 있습니다.
The_Cthulhu_Kid

2

하위 항목이 지연로드되는 시나리오에서 Eager-Loading을 강제하는 것으로 생각하십시오.

쿼리 EF가 데이터베이스로 전송하면 처음에는 더 큰 결과가 생성되지만 액세스시 포함 된 항목에 액세스 할 때 후속 쿼리가 만들어지지 않습니다.

반면에 EF가 없으면 나중에 하위 항목에 처음 액세스 할 때 별도의 쿼리를 실행합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.