ToLookup과 GroupBy가 다른 이유는 무엇입니까?


111

.ToLookup<TSource, TKey>를 반환합니다 ILookup<TKey, TSource>. ILookup<TKey, TSource>또한 인터페이스를 구현 IEnumerable<IGrouping<TKey, TSource>>합니다.

.GroupBy<TSource, TKey>를 반환합니다 IEnumerable<IGrouping<Tkey, TSource>>.

ILookup에는 편리한 인덱서 속성이 있으므로 사전과 같은 (또는 조회와 같은) 방식으로 사용할 수 있지만 GroupBy는 사용할 수 없습니다. 인덱서가없는 GroupBy는 작업하기가 어렵습니다. 반환 개체를 참조 할 수있는 거의 유일한 방법은 개체를 반복하거나 다른 LINQ 확장 메서드를 사용하는 것입니다. 즉, GroupBy가 작동하는 경우 ToLookup도 작동합니다.

이 모든 것이 왜 내가 GroupBy를 귀찮게할까요? 왜 존재해야합니까?


7
GroupByIs IQuerable, ILookupis not
Magnus

5
GroupBy는 목록을 열거하지 않습니다. ToLookup 은 ToList / ToArray와 같은 방식으로 열거합니다
Aducci

3
나는이 주장에 관한의 중복의 문제부터 재개이 지명 한 IGrouping 보다는 GROUPBYiLookup으로 보다는 ToLookup . 이들 간의 차이점은 이들 간의 차이점과 다릅니다. 이것은 질문들 사이의 답변의 차이에서 분명해야합니다.
Sam

1
둘 다를 생성 Lookup하지만 GroupBy결과가 열거 될 때 생성합니다. referencesource.microsoft.com/#System.Core/System/Linq/…
Slai

답변:


175

왜 내가 GroupBy를 괴롭 히겠습니까? 왜 존재해야합니까?

10 억 개의 행이있는 원격 데이터베이스 테이블을 나타내는 개체에서 ToLookup을 호출하면 어떻게됩니까?

수십억 개의 행이 유선으로 전송되고 로컬에서 조회 테이블을 빌드합니다.

이러한 개체에 대해 GroupBy를 호출하면 어떻게됩니까?

쿼리 개체가 작성됩니다. 이야기의 끝.

해당 쿼리 개체가 열거 되면 데이터베이스 서버 에서 테이블 분석이 수행 되고 그룹화 된 결과는 요청 시 한 번에 몇 개씩 다시 전송됩니다 .

논리적으로는 동일하지만 성능에 미치는 영향 은 완전히 다릅니다. ToLookup을 호출한다는 것은 그룹별로 정리 된 전체 내용의 캐시를 원한다는 것을 의미 합니다. GroupBy를 호출하는 것은 " '그룹별로 구성하면 이러한 것들이 어떻게 생겼을까 요?'라는 질문을 나타내는 개체를 만들고 있습니다."를 의미합니다.


6
포스터는 특정 IQueryable<T>표현을 대상으로하지 않습니다 . 귀하의 답변은 그 상황을 다루지 만, 평범한 ol IEnumerable<T>(LINQ-to-Objects) 일 때 하나를 다른 것보다 사용할 이유가없는 것처럼 보일 수 있습니다. 이것이 @Shlomo가 얻으려고하는 것입니다. 아니IQueryable<T> 경우, 그러나 LINQ - 투 - 객체의 경우.
casperOne

21
@casperOne : 내 요점을 이해하지 못한 것 같습니다. LINQ-to-objects의 경우 에도 GroupBy를 호출 해도 컬렉션을 반복하지 않습니다. (Aducci가 삭제 한 답변에서 지적했듯이.) 그것은 근본적인 차이점입니다.
Eric Lippert

12
@EricLippert :하지만 그저 구현의 부작용 일 뿐입니 까 아니면 구현에 어떤 변경이 가해지더라도 ToLookup을 호출 할 때 열거 형이 반복된다는 보장 이 있습니까?

9
@Will : 당신은 훌륭한 지적을합니다. 문서는 ToLookup이 "열심히"있음을 보장하지 않습니다. 아마 주목해야 할 것입니다.
Eric Lippert 2012

10
열망이 그것을 설명합니다. 'ToMetaType'의 언어는 열의를 의미한다고 생각합니다. 분명히 구현에 달려 있습니다. 다른 'To'는 모두 열망합니다 (ToList, ToArray, ToDictionary). 감사합니다.
Shlomo

98

간단한 LINQ 세계 용어로 :

  • ToLookup() -즉시 실행
  • GroupBy() -연기 된 실행

17

두 가지는 비슷하지만 다른 시나리오에서 사용됩니다. .ToLookup()이미 모든 그룹 (그룹의 콘텐츠가 아님)이 열심히로드 된 즉시 사용 가능한 객체를 반환합니다. 반면, .GroupBy()지연로드 된 그룹 시퀀스를 반환합니다.

다른 LINQ 공급자는 그룹의 빠른로드 및 지연로드에 대해 다른 동작을 가질 수 있습니다. LINQ-to-Object에서는 거의 차이가 없지만 LINQ-to-SQL (또는 LINQ-to-EF 등)에서는 그룹화 작업이 클라이언트가 아닌 데이터베이스 서버에서 수행되므로 원하는 경우가 있습니다. ( HAVING절 을 생성하는 ) 그룹 키에 대해 추가 필터링을 수행 한 다음 모든 그룹이 아닌 일부 그룹 만 가져옵니다. .ToLookup()모든 항목이 열심히 그룹화되어 있으므로 이러한 의미를 허용하지 않습니다.

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