2012-04-20 4 views
1

컬렉션에 일치하는 항목이 하나 뿐이라는 것을 알고 있다면 Linq에게이를 알릴 방법이 있습니까? 그래서 발견하면 검색을 중단합니다.항목을 찾은 후 linq 쿼리를 중단 하시겠습니까?

두 항목 모두 하나의 항목을 반환하기 전에 전체 컬렉션을 검색한다고 가정합니다.

var fred = _people.Where((p) => p.Name == "Fred").First(); 
var bill = _people.Where((p) => p.Name == "Bill").Take(1); 

편집 : 사람들은 FirstOrDefault, 또는 SingleOrDefault에 집착 보인다. 이것들은 제 질문과는 관련이 없습니다. 콜렉션이 비어있는 경우 단순히 기본값을 제공합니다. 앞서 말한 것처럼 내 컬렉션에는 일치하는 항목이 하나 있습니다.

AakashM의 의견은 저에게 가장 큰 관심사입니다. 나는 내 가정이 틀렸다는 것을 알았지 만 나는 왜 그런지 관심이있다. 예를 들어, linq 개체에 내 예제 코드에서 Where() 함수를 실행하는 경우 반환 값에 대한 연산이 추가로 있다는 것을 어떻게 알 수 있습니까?

+4

기본 제공 업체에 따라 다르지만, 귀하의 가정은 자주 부정확 할 것입니다. – AakashM

+1

FirstOrDefault를 사용합니다. 일단 항목을 찾으면 중지하고 컬렉션의 나머지 항목을 검색하지 않습니다. 그렇지 않으면 항목이없는 경우 null을 반환합니다. 둘 이상의 항목이있는 경우 예외를 throw하려면 SingleOrDefault를 사용하지만 전체 선택을 검색합니다. – ThePower

+0

@AakashM : 내 질문을 조금 편집했습니다. 당신은 전혀 논평 할 수 있습니까? – GazTheDestroyer

답변

5

당신의 가정은 잘못된 것입니다. LINQ는 지연 실행과 lazy evaluation을 많이 사용합니다. 즉, Where()으로 전화를 걸면 실제로 컬렉션을 반복하지 않습니다. 반환하는 객체를 반복 할 때만 원본 컬렉션을 반복합니다. 그리고 그것은 게으른 방식으로 그것을 할 것입니다 : 필요한만큼만.

그래서, 어떤 쿼리도 전체 컬렉션을 반복하지 않습니다. 둘 다 첫 번째 요소를 찾은 지점까지만 반복하여 멈 춥니 다.

실제로 두 번째 쿼리 (Take())는 수행하지 않습니다. 결과를 반복하는 경우에만 소스 컬렉션을 반복합니다.

이 모든 것은 개체에 대한 LINQ에 적용됩니다. 다른 공급자 (LINQ to SQL 및 기타)는 다르게 동작 할 수 있지만 적어도 지연된 실행의 원칙은 일반적으로 유지됩니다.

+0

D' oh! 당연하지. 나는 LINQ의 연기 된 실행에 대해 읽었지만 잊어 버렸습니다. 설명 해줘서 고마워. – GazTheDestroyer

-1

대체물 .Where(.SingleorDefault( 이렇게하면 처음이자 유일한 항목을 찾을 수 있습니다.

그러나 주어진 번호에 대해서는이 작업을 수행 할 수 없습니다. 2 개 항목이 필요하면 전체 컬렉션을 가져와야합니다.

그러나 시간에 대해 걱정할 필요가 없습니다. 가장 많은 노력은 데이터베이스 연결을 열고 쿼리를 설정하는 데 사용됩니다. 쿼리를 실행하는 데 많은 시간이 걸리지 않으므로 쿼리를 중간에 중단 할 이유가 없습니다 .-

+0

SingleOrDefault는 '첫 번째'항목을 찾지 않습니다. 항목이 2 개있는 경우 예외가 발생합니다. FirstOrDefault를 설명하고 있습니다 – ThePower

+0

"첫 번째 AND 전용"이라고 ... – Flater

0

나는 전체 컬렉션을 검색하지 않을 것이라고 생각합니다. First() 첫 번째 경기가 끝나면 즉시 반환됩니다. 하지만 대신 FirstOrDefault()을 사용하는 것이 좋습니다.

EDIT : 소스 요소가없는 경우 First() 메소드가 예외를 발생

:

차 (MSDN)에서 First() 사이 FirstOrDefault(). 소스 시퀀스가 ​​비어있을 때 대신 기본값을 반환하려면 FirstOrDefault() 메서드를 사용하십시오.

Enumerable.First