2011-11-11 4 views
2

엔티티 프레임 워크와 POCO 객체로 작업 중이므로 LazyLoading이 켜져 있습니다.엔티티 프레임 워크 4 지연로드 엔티티 세트

개체와 관련된 모음으로 작업하고있는 경우 모음이 완전히로드 된시기와 상황은 언제입니까?

나는이

Order.OrderItems.Count() 
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

의 각을 호출 할 경우 이들의이 OrderItems에 모음의 전체로드를 보장합니까?

를 조회 한 후

context.LoadProperty(order, “OrderItems”) 

를 조회하거나 코드의 점에서 우리는

Order.Include(“OrderItems”) 

를 호출하지만 때로는이 항상 발생하지 않습니다 깨달았다 - 나는 알고 싶다 이 결과는 발생하지 않습니다. 나는 일반적으로 당신이 그들의 결과를 통해, 또는 추가 foreach ToListToArray이 등이이에 어떻게 Linq에있다 할 때까지 데이터를로드하지 마십시오

답변

4

의 LINQ 방법과 지식 격차의 비트를 가지고 생각 엔터티 공급자를 사용하면 메서드를 체인화하고 최종 구조에 대해서만 쿼리를 작성할 수 있습니다.

메서드가 IQueryable 또는 IEnumerable을 반환하면 Linq이 해당 시점에 데이터를로드하지 않을 것입니다.

그러나 : 가장 바깥 쪽 쿼리

Order.OrderItems.Count() 
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

, Linq는 부울 값 또는 다음 즉시 쿼리를 실행해야합니다 정수를 반환해야합니다. 그러나 중첩 된 쿼리는 외부 쿼리가 평가 될 때까지 평가되지 않으므로 좀 더 복잡해집니다. 에 관해서는

는 :

Order.Include("OrderItems") 

나는 Include 자체에 대한 쿼리를 해결할 수없는 것으로 판단된다. 다른 쿼리를 만들 때이 데이터를 사용하여 추가 데이터를 피기 백합니다.

http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx

당신의 아이디어를 줄 것이다 : 당신이 Linq에 작동하는 방법 (일반적으로) 알고 싶다면

Linq는 일반적으로

, 당신은 기사의 집합을 확인하실 수 있습니다 IEnumerable을 연기 할 수 있고 평가해야하는 경우 그것은 당신에게 Linq to Entities 공급자에 대한 모든 것을 말해주지는 않지만, 지식의 좋은 부분이 전달 될 것입니다.

+0

감사합니다. @Merlyn Morgan-Graham. 'Linq가 부울 값이나 정수를 반환해야하는 경우 즉시 쿼리를 실행할 가능성이 있음을 명확히 할 수 있습니까?' http://msmvps.com/blogs/jon_skeet/archive/2010/12/28/reimplementing-linq-to-objects-part-10-any-and-all.aspx를 살펴본 결과 Any 및 모두 실제로는 커버 아래의 결과를 반복하므로 컬렉션을 자동으로 실현합니다. 따라서 Any/All이 외부 쿼리에서 컬렉션을로드하는 것처럼 보입니다. –

+1

@TimBrown : "Any 및 All이 실제로 커버 아래의 결과를 반복하므로 컬렉션을 자동으로 인식합니다." 나는 이것이 정확히 내가 말한 것, 바로 weasel-speak ("아마도"= ** 항상 **, LOL)라고 생각합니다. 나는 단지 그 문장을 정리했으면 좋겠다. –

+0

또한, 중첩 된 쿼리에 의해, 나는'Order.OrderItems.Where (i => i.Rebates.Any())'와 같은 것을 의미한다 - Rebates.Any()는 외부 쿼리가 평가. –

3
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

은 검색어입니다.

.ToList() (또는 개체로 구체화하기위한 다른 반복기)를 호출하면 이러한 쿼리가 실행됩니다..Include을 사용하면 쿼리를 실행할 때 포함 된 속성이 채워집니다 (쿼리에 해당 테이블에 대한 조인이 포함됨). Any 또는 All (또는 Where과 같은 필터 확장자)을 사용하면 조건 (다른 테이블의 조건 일 수 있음) 만 추가되지만 OrderItems는 SQL select에 배치되지 않으므로 .Include을 사용하지 않으면로드되지 않습니다.

-

이 질문과 관련,하지만 당신이 신선한, 그리고 당신이 호출이있는 경우, (실행 쿼리) ToList를 호출하기 전에 쿼리에 SkipTake을 추가하는 것을 기억하지, 난 사람들을 보았다 ToList을 호출하고 페이징을하기 전에 전체 테이블을 메모리로 읽는 것.

+0

+1 페이징 조언. 정말? 나는 사람들이 페이징을 구현하려고 할 때'Skip'과'Take'와 같은 것을 찾아 낼 것이라고 생각했다. 그것이 Linq의 요점입니다. 이상한 ... :) –

+0

글쎄, 종종 사양이 없으며 사람들이 프로토 타입을 만들 때 "페이징을 사용할 수 없습니다"라는 지시문이 있습니다. 나중에 프로토 타입이 릴리스되고 xx 레코드가있는 후에 "그리드가 너무 많은 공간을 차지하므로"페이징을 추가하라는 지시가 있습니다. linq이 어떻게 작동하는지 모르는 새로운 개발자는 종종 컨트롤러/코드 숨김에있는 변수에 Skip/Take 만 추가하고 전체 테이블을 포함하는 변수는 인식하지 않습니다. 그리고 이것은 linq (foreach 루프에서 "하위 쿼리"를 상상해보십시오)의 잘못된 사용으로 인해 발생하는 성능 문제 중 가장 간단한 것입니다. –

+0

고맙습니다. @Goran Obradovic에 감사드립니다. '이 쿼리는 호출 할 때 실행됩니다 .ToList()'는 부울 또는 int를 반환하는 메서드가 컬렉션을로드한다는 첫 번째 대답과 모순되는 것처럼 보입니다. 내가 오해 한 경우 사과드립니다. 모순이 있습니까? –

관련 문제