IQueryable<T> 와 IEnumerable<T> 는 거의 동일한 API 정의를 가진다. 따라서 이 두 인터페이스는
상호 교환 가능하다고 생각할 것이며 실제로도 대부분 그렇다. 이는 사실 의도한 설계이기도 하다.
하지만 시퀀스는 그냥 시퀀스일 뿐이어서 항상 이 둘을 서로 대체하여 사용할 수 있는 것은 아니다.
실상 이 둘은 동작 방식도 매우 다르고 성능 차이도 크게 난다. 다음의 예를 살펴보자.
// 첫 번째 예
var q =
from c in dbContext.Customers
where c.City == "London"
select c;
var finalAnswer = from c in q
orderby c.Name
select c;
// finalAnswer에 대한 순회 코드는 생략
// 두 번째 예
var q =
(from c in dbContext.Customers
where c.City == "London"
select c).AsEnumerable();
var finalAnswer = from c in q
orderby c.Name
select c;
// finalAnswer에 대한 순회 코드는 생략
두 예제의 결괏값은 동일하다. 하지만 그 동작 방식은 매우 상이하다.
첫 번째 예는 일반적인 LINQ to SQL 쿼리이며 IQueryable<T> 의 기능을 사용한다.
두 번째 예는 데이터베이스 객체를 IEnumerable<T> 시퀀스로 변경하기 때문에 데이터베이스가
아니라 로컬 컴퓨터에서 더 많은 작업을 수행하게 된다. 이 쿼리는 지연 평가와 LINQ to SQL 내의
IQueryable<T> 를 동시에 사용한다.
첫 번째 예의 경우 LINQ to SQL 라이브러리가 모든 쿼리문을 결합하여 단번에 SQL 결과를 생성한다.
앞의 예제의 경우 where 절과 order 절이 모두 결합된 단일의 T-SQL 구문을 만들어서 단 한 차례
데이터베이스를 호출한다.
두 번째 예의 경우 첫 번째 수행된 쿼리문이 IEnumerable<T> 시퀀스를 반환하므로 그 다음 작업은
LINQ to Objects 구현체와 델리게이트를 이용하여 수행된다. 첫 번째 쿼리문이 수행되면 데이터베이
스 에 쿼리를 전달하여 City값이 London인 모든 레코드를 가져오게 된다. 이후 가져온 레코드들을